diff --git a/Makefile b/Makefile index 8010e80e8fc..3ffe576a676 100644 --- a/Makefile +++ b/Makefile @@ -66,23 +66,33 @@ spike-tandem ?= $(SPIKE_TANDEM) SPIKE_INSTALL_DIR ?= $(root-dir)/tools/spike + # setting additional xilinx board parameters for the selected board ifeq ($(BOARD), genesys2) XILINX_PART := xc7k325tffg900-2 XILINX_BOARD := digilentinc.com:genesys2:part0:1.1 CLK_PERIOD_NS := 20 + XILINX_JTAG_PROBE_FILES := corev_apu/riscv-dbg/src/dmi_jtag_tap.sv corev_apu/riscv-dbg/src/dmi_jtag.sv corev_apu/riscv-dbg/src/dmi_cdc.sv else ifeq ($(BOARD), kc705) XILINX_PART := xc7k325tffg900-2 XILINX_BOARD := xilinx.com:kc705:part0:1.5 CLK_PERIOD_NS := 20 + XILINX_JTAG_PROBE_FILES := corev_apu/riscv-dbg/src/dmi_jtag_tap.sv corev_apu/riscv-dbg/src/dmi_jtag.sv corev_apu/riscv-dbg/src/dmi_cdc.sv else ifeq ($(BOARD), vc707) XILINX_PART := xc7vx485tffg1761-2 XILINX_BOARD := xilinx.com:vc707:part0:1.3 CLK_PERIOD_NS := 20 + XILINX_JTAG_PROBE_FILES := corev_apu/riscv-dbg/src/dmi_jtag_tap.sv corev_apu/riscv-dbg/src/dmi_jtag.sv corev_apu/riscv-dbg/src/dmi_cdc.sv else ifeq ($(BOARD), nexys_video) XILINX_PART := xc7a200tsbg484-1 XILINX_BOARD := digilentinc.com:nexys_video:part0:1.1 CLK_PERIOD_NS := 40 + XILINX_JTAG_PROBE_FILES := corev_apu/riscv-dbg/src/dmi_jtag_tap.sv corev_apu/riscv-dbg/src/dmi_jtag.sv corev_apu/riscv-dbg/src/dmi_cdc.sv +else ifeq ($(BOARD), arty_a7_100) + XILINX_PART := xc7a100tcsg324-1 + XILINX_BOARD := digilentinc.com:arty-a7-100:part0:1.1 + CLK_PERIOD_NS := 40 + XILINX_JTAG_PROBE_FILES := corev_apu/fpga/src/riscv_dbg_bscane_backport/dmi_bscane_tap.sv corev_apu/fpga/src/riscv_dbg_bscane_backport/dmi_jtag.sv corev_apu/fpga/src/riscv_dbg_bscane_backport/dmi_cdc.sv else $(error Unknown board - please specify a supported FPGA board) endif @@ -170,9 +180,7 @@ src := $(if $(spike-tandem),verif/tb/core/uvma_core_cntrl_pkg.sv) corev_apu/rv_plic/rtl/rv_plic_gateway.sv \ corev_apu/rv_plic/rtl/plic_regmap.sv \ corev_apu/rv_plic/rtl/plic_top.sv \ - corev_apu/riscv-dbg/src/dmi_cdc.sv \ - corev_apu/riscv-dbg/src/dmi_jtag.sv \ - corev_apu/riscv-dbg/src/dmi_jtag_tap.sv \ + $(XILINX_JTAG_PROBE_FILES) \ corev_apu/riscv-dbg/src/dm_csrs.sv \ corev_apu/riscv-dbg/src/dm_mem.sv \ corev_apu/riscv-dbg/src/dm_sba.sv \ @@ -184,6 +192,11 @@ src := $(if $(spike-tandem),verif/tb/core/uvma_core_cntrl_pkg.sv) vendor/pulp-platform/common_cells/src/rstgen.sv \ vendor/pulp-platform/common_cells/src/addr_decode.sv \ vendor/pulp-platform/common_cells/src/stream_register.sv \ + vendor/pulp-platform/common_cells/src/cdc_2phase_clearable.sv \ + vendor/pulp-platform/common_cells/src/cdc_reset_ctrlr.sv \ + vendor/pulp-platform/common_cells/src/cdc_reset_ctrlr_pkg.sv \ + vendor/pulp-platform/common_cells/src/cdc_4phase.sv \ + vendor/pulp-platform/common_cells/src/sync.sv \ vendor/pulp-platform/axi/src/axi_cut.sv \ vendor/pulp-platform/axi/src/axi_join.sv \ vendor/pulp-platform/axi/src/axi_delayer.sv \ diff --git a/corev_apu/fpga/scripts/run.tcl b/corev_apu/fpga/scripts/run.tcl index 9ba9d4e1878..9da65d12dc1 100644 --- a/corev_apu/fpga/scripts/run.tcl +++ b/corev_apu/fpga/scripts/run.tcl @@ -24,6 +24,8 @@ if {$::env(BOARD) eq "genesys2"} { add_files -fileset constrs_1 -norecurse constraints/vc707.xdc } elseif {$::env(BOARD) eq "nexys_video"} { add_files -fileset constrs_1 -norecurse constraints/nexys_video.xdc +} elseif {$::env(BOARD) eq "arty_a7_100"} { + add_files -fileset constrs_1 -norecurse constraints/arty_a7_100.xdc } else { exit 1 } @@ -69,6 +71,10 @@ if {$::env(BOARD) eq "genesys2"} { read_verilog -sv {src/nexys_video.svh ../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh} set file "src/nexys_video.svh" set registers "../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh" +} elseif {$::env(BOARD) eq "arty_a7_100"} { + read_verilog -sv {src/arty_a7_100.svh ../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh} + set file "src/arty_a7_100.svh" + set registers "../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh" } else { exit 1 } diff --git a/corev_apu/fpga/scripts/write_cfgmem.tcl b/corev_apu/fpga/scripts/write_cfgmem.tcl index 5138011f43c..578a9066d4f 100644 --- a/corev_apu/fpga/scripts/write_cfgmem.tcl +++ b/corev_apu/fpga/scripts/write_cfgmem.tcl @@ -34,6 +34,8 @@ if {$::env(BOARD) eq "genesys2"} { write_cfgmem -format mcs -interface SPIx4 -size 128 -loadbit "up 0x0 $bitfile" -file $mcsfile -force } elseif {$::env(BOARD) eq "nexys_video"} { write_cfgmem -format mcs -interface SPIx4 -size 256 -loadbit "up 0x0 $bitfile" -file $mcsfile -force +} elseif {$::env(BOARD) eq "arty_a7_100"} { + write_cfgmem -format mcs -interface SPIx1 -size 128 -loadbit "up 0x0 $bitfile" -file $mcsfile -force } else { exit 1 } diff --git a/corev_apu/fpga/src/ariane_xilinx.sv b/corev_apu/fpga/src/ariane_xilinx.sv index 20e77f77c2c..051acdd4e11 100644 --- a/corev_apu/fpga/src/ariane_xilinx.sv +++ b/corev_apu/fpga/src/ariane_xilinx.sv @@ -170,13 +170,49 @@ module ariane_xilinx ( input logic [ 7:0] sw , output logic fan_pwm , input logic trst_n , +`elsif ARTY_A7_100 + input logic board_clk_i , + input logic cpu_resetn , + + inout wire [15:0] ddr3_dq , + inout wire [ 1:0] ddr3_dqs_n , + inout wire [ 1:0] ddr3_dqs_p , + output wire [13:0] ddr3_addr , + output wire [ 2:0] ddr3_ba , + output wire ddr3_ras_n , + output wire ddr3_cas_n , + output wire ddr3_we_n , + output wire ddr3_reset_n, + output wire [ 0:0] ddr3_ck_p , + output wire [ 0:0] ddr3_ck_n , + output wire [ 0:0] ddr3_cke , + output wire [ 1:0] ddr3_dm , + output wire [ 0:0] ddr3_odt , + output wire ddr3_cs_n , + + output wire eth_rst_n , + input wire eth_rxck , + input wire eth_rxctl , + input wire [3:0] eth_rxd , + output wire eth_txck , + output wire eth_txctl , + output wire [3:0] eth_txd , + inout wire eth_mdio , + output logic eth_mdc , + output logic [ 3:0] led , + input logic [ 3:0] sw , + + // 25 MHz reference clock for the PHY interface + output wire eth_phy_ref_clk, `endif // SPI output logic spi_mosi , input logic spi_miso , output logic spi_ss , output logic spi_clk_o , - // common part + // JTAG +`ifndef ARTY_A7_100 + // ARTY uses dmi_bscane // input logic trst_n , input logic tck , input logic tms , @@ -281,6 +317,9 @@ assign trst_n = ~trst; `elsif NEXYS_VIDEO logic cpu_reset; assign cpu_reset = ~cpu_resetn; +`elsif ARTY_A7_100 +logic cpu_reset; +assign cpu_reset = ~cpu_resetn; `endif logic pll_locked; @@ -306,6 +345,30 @@ assign test_en = 1'b0; logic [NBSlave-1:0] pc_asserted; +`ifdef ARTY_A7_100 + +rstgen i_rstgen_main ( + .clk_i ( clk ), + .rst_ni ( pll_locked & (~ndmreset) & rst_n ), // need to delay resetting the rest of the system until both DRAM and debug module ready + .test_mode_i ( test_en ), + .rst_no ( ndmreset_n ), + .init_no ( ) // keep open +); + +// DDR reset is not in phase, and might be too fast +// so we synchronize the board-level reset in as well +rstgen i_rstgen_dm ( + .clk_i ( clk ), + .rst_ni ( pll_locked & cpu_resetn & ~(ddr_sync_reset) ), + .test_mode_i ( test_en ), + .rst_no ( rst_n ), + .init_no ( ) // keep open +); + +assign rst = ~rst_n; + +`else + rstgen i_rstgen_main ( .clk_i ( clk ), .rst_ni ( pll_locked & (~ndmreset) ), @@ -317,6 +380,7 @@ rstgen i_rstgen_main ( assign rst_n = ~ddr_sync_reset; assign rst = ddr_sync_reset; +`endif // --------------- // AXI Xbar // --------------- @@ -366,6 +430,25 @@ axi_xbar_intf #( .default_mst_port_i ( '0 ) ); +`ifdef ARTY_A7_100 +// when selecting the input files, we use "dmi_bscane_tap" instead of "dmi_jtag_tag". +// dmi_bscane_tap uses Xilinx' BSCANE primitive to access the USB JTAG chain +// hence, no JTAG signals needed +logic tck; +logic tms; +logic trst_n; +logic tdi; +logic tdo; + +assign tck = 1'b0; +assign tms = 1'b0; +assign tdi = 1'b0; + +// reset of the JTAG tap +// tied to external reset; should not be the same as CPU to avoid loop +assign trst_n = cpu_resetn; + +`endif // --------------- // Debug Module // --------------- @@ -853,6 +936,14 @@ end // Peripherals // --------------- `ifdef KC705 +`define ONLY_FOUR_LEDS_SWITCHES +`endif + +`ifdef ARTY_A7_100 +`define ONLY_FOUR_LEDS_SWITCHES +`endif + +`ifdef ONLY_FOUR_LEDS_SWITCHES logic [7:0] unused_led; logic [3:0] unused_switches = 4'b0000; `endif @@ -881,6 +972,9 @@ ariane_peripherals #( `elsif NEXYS_VIDEO .InclSPI ( 1'b1 ), .InclEthernet ( 1'b0 ) + `elsif ARTY_A7_100 + .InclSPI ( 1'b1 ), + .InclEthernet ( 1'b0 ) // Ethernet does not meet timing `endif ) i_ariane_peripherals ( .clk_i ( clk ), @@ -911,7 +1005,7 @@ ariane_peripherals #( .spi_mosi ( spi_mosi ), .spi_miso ( spi_miso ), .spi_ss ( spi_ss ), - `ifdef KC705 + `ifdef ONLY_FOUR_LEDS_SWITCHES .leds_o ( {led[3:0], unused_led[7:4]}), .dip_switches_i ( {sw, unused_switches} ) `else @@ -1144,6 +1238,28 @@ xlnx_clk_gen i_xlnx_clk_gen ( .clk_in1 ( ddr_clock_out ) // 100MHz input clock ); +`elsif ARTY_A7_100 +logic sys_clk_i; + +// clock input buffer +// allows us to share the clock between MIG and clkgen +// MIG output clock is not 100 MHz on Arty +BUFG( + .I(board_clk_i), + .O(sys_clk_i) +); + +xlnx_clk_gen i_xlnx_clk_gen ( + .clk_out1 ( clk ), // 25 MHz + .clk_out2 ( phy_tx_clk ), // 125 MHz (for RGMII PHY) + .clk_out3 ( eth_clk ), // 125 MHz quadrature (90 deg phase shift) + .clk_out4 ( sd_clk_sys ), // 50 MHz clock + .clk_out5 ( clk_200MHz_ref ), // 200 MHz clock + .clk_out6 ( eth_phy_ref_clk ), // 25 MHz reference for PHY + .reset ( cpu_reset ), + .locked ( pll_locked ), + .clk_in1 ( sys_clk_i ) // 100MHz input clock +); `else xlnx_clk_gen i_xlnx_clk_gen ( @@ -1904,6 +2020,77 @@ axi_clock_converter_0 pcie_axi_clock_converter ( .s_axi_rvalid ( pcie_dwidth_axi_rvalid ), .s_axi_rready ( pcie_dwidth_axi_rready ) ); +`elsif ARTY_A7_100 + + +xlnx_mig_7_ddr3 i_ddr ( + .sys_clk_i ( sys_clk_i ), + .clk_ref_i ( clk_200MHz_ref ), + .ddr3_dq, + .ddr3_dqs_n, + .ddr3_dqs_p, + .ddr3_addr, + .ddr3_ba, + .ddr3_ras_n, + .ddr3_cas_n, + .ddr3_we_n, + .ddr3_reset_n, + .ddr3_ck_p, + .ddr3_ck_n, + .ddr3_cke, + .ddr3_cs_n, + .ddr3_dm, + .ddr3_odt, + .mmcm_locked ( ), // keep open + .app_sr_req ( '0 ), + .app_ref_req ( '0 ), + .app_zq_req ( '0 ), + .app_sr_active ( ), // keep open + .app_ref_ack ( ), // keep open + .app_zq_ack ( ), // keep open + .ui_clk ( ddr_clock_out ), + .ui_clk_sync_rst ( ddr_sync_reset ), + .aresetn ( ndmreset_n ), + .s_axi_awid, + .s_axi_awaddr ( s_axi_awaddr[28:0] ), + .s_axi_awlen, + .s_axi_awsize, + .s_axi_awburst, + .s_axi_awlock, + .s_axi_awcache, + .s_axi_awprot, + .s_axi_awqos, + .s_axi_awvalid, + .s_axi_awready, + .s_axi_wdata, + .s_axi_wstrb, + .s_axi_wlast, + .s_axi_wvalid, + .s_axi_wready, + .s_axi_bready, + .s_axi_bid, + .s_axi_bresp, + .s_axi_bvalid, + .s_axi_arid, + .s_axi_araddr ( s_axi_araddr[28:0] ), + .s_axi_arlen, + .s_axi_arsize, + .s_axi_arburst, + .s_axi_arlock, + .s_axi_arcache, + .s_axi_arprot, + .s_axi_arqos, + .s_axi_arvalid, + .s_axi_arready, + .s_axi_rready, + .s_axi_rid, + .s_axi_rdata, + .s_axi_rresp, + .s_axi_rlast, + .s_axi_rvalid, + .init_calib_complete ( ), // keep open + .sys_rst ( cpu_resetn ) +); `endif endmodule diff --git a/corev_apu/fpga/src/bootrom/Makefile b/corev_apu/fpga/src/bootrom/Makefile index 35c2b872ea7..c6d8fc131d4 100644 --- a/corev_apu/fpga/src/bootrom/Makefile +++ b/corev_apu/fpga/src/bootrom/Makefile @@ -9,6 +9,14 @@ HALF_CLOCK_FREQUENCY ?= 12500000 #12.5MHz UART_BITRATE ?= 57600 HAS_ETHERNET ?= 0 else +ifeq ($(BOARD), arty_a7_100) +DRAM_SIZE_64 ?= 0x10000000 #256MB +DRAM_SIZE_32 ?= 0x08000000 #128MB +CLOCK_FREQUENCY ?= 25000000 #12.5MHz +HALF_CLOCK_FREQUENCY ?= 12500000 #6.25MHz +UART_BITRATE ?= 57600 +HAS_ETHERNET ?= 0 +else DRAM_SIZE_64 ?= 0x40000000 #1GB DRAM_SIZE_32 ?= 0x08000000 #128MB CLOCK_FREQUENCY ?= 50000000 #50MHz @@ -16,6 +24,7 @@ HALF_CLOCK_FREQUENCY ?= 25000000 #25MHz UART_BITRATE ?= 115200 HAS_ETHERNET ?= 1 endif +endif CC = $(RISCV)/bin/${CROSSCOMPILE}gcc OBJCOPY = $(RISCV)/bin/$(CROSSCOMPILE)objcopy diff --git a/corev_apu/fpga/xilinx/xlnx_clk_gen/tcl/run.tcl b/corev_apu/fpga/xilinx/xlnx_clk_gen/tcl/run.tcl index 2754a49ffe8..5955de1459a 100644 --- a/corev_apu/fpga/xilinx/xlnx_clk_gen/tcl/run.tcl +++ b/corev_apu/fpga/xilinx/xlnx_clk_gen/tcl/run.tcl @@ -23,6 +23,24 @@ if {$::env(BOARD) eq "nexys_video"} { CONFIG.CLKOUT5_REQUESTED_OUT_FREQ {200} \ CONFIG.CLKIN1_JITTER_PS {50.0} \ ] [get_ips $ipName] +} elseif {$::env(BOARD) eq "arty_a7_100"} { + set_property -dict [list CONFIG.PRIM_IN_FREQ {100.000} \ + CONFIG.NUM_OUT_CLKS {6} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {true} \ + CONFIG.CLKOUT4_USED {true} \ + CONFIG.CLKOUT5_USED {true} \ + CONFIG.CLKOUT6_USED {true} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {25} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {125} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {125} \ + CONFIG.CLKOUT3_REQUESTED_PHASE {90.000} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {50} \ + CONFIG.CLKOUT5_REQUESTED_OUT_FREQ {200} \ + CONFIG.CLKOUT6_REQUESTED_OUT_FREQ {25} \ + CONFIG.CLKIN1_JITTER_PS {100.0} \ + CONFIG.PRIM_SOURCE {No_buffer} \ + ] [get_ips $ipName] } else { set_property -dict [list CONFIG.PRIM_IN_FREQ {200.000} \ CONFIG.NUM_OUT_CLKS {4} \ diff --git a/corev_apu/fpga/xilinx/xlnx_ila/tcl/run.tcl b/corev_apu/fpga/xilinx/xlnx_ila/tcl/run.tcl index 9aff7b113ab..7d72564fe7f 100644 --- a/corev_apu/fpga/xilinx/xlnx_ila/tcl/run.tcl +++ b/corev_apu/fpga/xilinx/xlnx_ila/tcl/run.tcl @@ -7,10 +7,49 @@ create_project $ipName . -force -part $partNumber set_property board_part $boardName [current_project] create_ip -name ila -vendor xilinx.com -library ip -module_name $ipName -set_property -dict [list CONFIG.C_NUM_OF_PROBES {8} \ - CONFIG.C_PROBE3_WIDTH {4} \ - CONFIG.C_PROBE6_WIDTH {4} \ - CONFIG.C_DATA_DEPTH {16384} \ +# probe 1 pll_locked +# probe 2 ndmreset_n +# probe 3 irq_i +# probe 4 ipi +# probe 5 timer_irq +# probe 6 debug_req +# probe7 araddr +# probe8 arvalid +# probe9 arready +# probe10 awaddr +# probe11 awvalid +# probe12 awready +# probe 13 wdata +# probe 14 wvalid +# probe 15 wready +# probe 16 rdata +# probe 17 rresp +# probe 18 rvalid +# probe 19 bvalid +# probe 20 bresp + +set_property -dict [list CONFIG.C_NUM_OF_PROBES {20} \ + CONFIG.C_PROBE0_WIDTH {1} \ + CONFIG.C_PROBE1_WIDTH {1} \ + CONFIG.C_PROBE2_WIDTH {2} \ + CONFIG.C_PROBE3_WIDTH {1} \ + CONFIG.C_PROBE4_WIDTH {1} \ + CONFIG.C_PROBE5_WIDTH {1} \ + CONFIG.C_PROBE6_WIDTH {64} \ + CONFIG.C_PROBE7_WIDTH {1} \ + CONFIG.C_PROBE8_WIDTH {1} \ + CONFIG.C_PROBE9_WIDTH {64} \ + CONFIG.C_PROBE10_WIDTH {1} \ + CONFIG.C_PROBE11_WIDTH {1} \ + CONFIG.C_PROBE12_WIDTH {64} \ + CONFIG.C_PROBE13_WIDTH {1} \ + CONFIG.C_PROBE14_WIDTH {1} \ + CONFIG.C_PROBE15_WIDTH {64} \ + CONFIG.C_PROBE16_WIDTH {2} \ + CONFIG.C_PROBE17_WIDTH {1} \ + CONFIG.C_PROBE18_WIDTH {1} \ + CONFIG.C_PROBE19_WIDTH {2} \ + CONFIG.C_DATA_DEPTH {4096} \ CONFIG.C_INPUT_PIPE_STAGES {1} \ ] [get_ips $ipName]