From 2bd64634dd53c097191f1768e0147f2aaebafffd Mon Sep 17 00:00:00 2001 From: Greg Chadwick Date: Fri, 5 Jan 2024 21:20:50 +0000 Subject: [PATCH] Add initial Sonata board support --- data/pins_sonata.xdc | 114 ++++++++++++++++++++++++++++++++++++ ibex_demo_system.core | 27 ++++++++- rtl/fpga/clkgen_sonata.sv | 83 ++++++++++++++++++++++++++ rtl/fpga/top_sonata.sv | 105 +++++++++++++++++++++++++++++++++ util/sonata-openocd-cfg.tcl | 33 +++++++++++ 5 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 data/pins_sonata.xdc create mode 100644 rtl/fpga/clkgen_sonata.sv create mode 100644 rtl/fpga/top_sonata.sv create mode 100644 util/sonata-openocd-cfg.tcl diff --git a/data/pins_sonata.xdc b/data/pins_sonata.xdc new file mode 100644 index 00000000..a12d06c2 --- /dev/null +++ b/data/pins_sonata.xdc @@ -0,0 +1,114 @@ +create_clock -period 40.000 -name mainclk -waveform {0.000 20.000} [get_ports mainclk] +create_clock -period 100.000 -name tck -waveform {0.000 50.000} [get_ports tck_i] + +set_property PACKAGE_PIN B13 [get_ports {userled[0]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[0]}] +set_property PACKAGE_PIN B14 [get_ports {userled[1]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[1]}] +set_property PACKAGE_PIN C12 [get_ports {userled[2]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[2]}] +set_property PACKAGE_PIN B12 [get_ports {userled[3]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[3]}] +set_property PACKAGE_PIN B11 [get_ports {userled[4]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[4]}] +set_property PACKAGE_PIN A11 [get_ports {userled[5]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[5]}] +set_property PACKAGE_PIN F13 [get_ports {userled[6]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[6]}] +set_property PACKAGE_PIN F14 [get_ports {userled[7]}] +set_property IOSTANDARD LVCMOS33 [get_ports {userled[7]}] + +set_property PACKAGE_PIN H17 [get_ports tck_i] +set_property IOSTANDARD LVCMOS33 [get_ports tck_i] +set_property PACKAGE_PIN G17 [get_ports td_i] +set_property IOSTANDARD LVCMOS33 [get_ports td_i] +set_property PACKAGE_PIN J14 [get_ports td_o] +set_property IOSTANDARD LVCMOS33 [get_ports td_o] +set_property PACKAGE_PIN H15 [get_ports tms_i] +set_property IOSTANDARD LVCMOS33 [get_ports tms_i] + +set_property PACKAGE_PIN D12 [get_ports {user_sw[0]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[0]}] +set_property PACKAGE_PIN D13 [get_ports {user_sw[1]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[1]}] +set_property PACKAGE_PIN B16 [get_ports {user_sw[2]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[2]}] +set_property PACKAGE_PIN B17 [get_ports {user_sw[3]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[3]}] +set_property PACKAGE_PIN A15 [get_ports {user_sw[4]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[4]}] +set_property PACKAGE_PIN A16 [get_ports {user_sw[5]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[5]}] +set_property PACKAGE_PIN A13 [get_ports {user_sw[6]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[6]}] +set_property PACKAGE_PIN A14 [get_ports {user_sw[7]}] +set_property IOSTANDARD LVCMOS33 [get_ports {user_sw[7]}] +set_property PACKAGE_PIN F5 [get_ports {nav_sw[0]}] +set_property IOSTANDARD LVCMOS18 [get_ports {nav_sw[0]}] +set_property PACKAGE_PIN D8 [get_ports {nav_sw[1]}] +set_property IOSTANDARD LVCMOS18 [get_ports {nav_sw[1]}] +set_property PACKAGE_PIN C7 [get_ports {nav_sw[2]}] +set_property IOSTANDARD LVCMOS18 [get_ports {nav_sw[2]}] +set_property PACKAGE_PIN E7 [get_ports {nav_sw[3]}] +set_property IOSTANDARD LVCMOS18 [get_ports {nav_sw[3]}] +set_property PACKAGE_PIN D7 [get_ports {nav_sw[4]}] +set_property IOSTANDARD LVCMOS18 [get_ports {nav_sw[4]}] +set_property PACKAGE_PIN K6 [get_ports {cherrierr[0]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[0]}] + +set_property PACKAGE_PIN L1 [get_ports {cherrierr[1]}] +set_property PACKAGE_PIN M1 [get_ports {cherrierr[2]}] +set_property PACKAGE_PIN K3 [get_ports {cherrierr[3]}] +set_property PACKAGE_PIN L3 [get_ports {cherrierr[4]}] +set_property PACKAGE_PIN N2 [get_ports {cherrierr[5]}] +set_property PACKAGE_PIN N1 [get_ports {cherrierr[6]}] +set_property PACKAGE_PIN M3 [get_ports {cherrierr[7]}] +set_property PACKAGE_PIN M2 [get_ports {cherrierr[8]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[1]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[2]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[3]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[4]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[5]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[6]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[7]}] +set_property IOSTANDARD LVCMOS33 [get_ports {cherrierr[8]}] + +set_property PACKAGE_PIN K5 [get_ports led_legacy] +set_property IOSTANDARD LVCMOS33 [get_ports led_legacy] +set_property PACKAGE_PIN L4 [get_ports led_cheri] +set_property IOSTANDARD LVCMOS33 [get_ports led_cheri] +set_property PACKAGE_PIN L6 [get_ports led_halted] +set_property IOSTANDARD LVCMOS33 [get_ports led_halted] +set_property PACKAGE_PIN L5 [get_ports led_bootok] +set_property IOSTANDARD LVCMOS33 [get_ports led_bootok] + +set_property PACKAGE_PIN R6 [get_ports lcd_rst] +set_property IOSTANDARD LVCMOS33 [get_ports lcd_rst] +set_property PACKAGE_PIN U4 [get_ports lcd_dc] +set_property IOSTANDARD LVCMOS33 [get_ports lcd_dc] +set_property PACKAGE_PIN R3 [get_ports lcd_copi] +set_property IOSTANDARD LVCMOS33 [get_ports lcd_copi] +set_property PACKAGE_PIN R5 [get_ports lcd_clk] +set_property IOSTANDARD LVCMOS33 [get_ports lcd_clk] +set_property PACKAGE_PIN P5 [get_ports lcd_cs] +set_property IOSTANDARD LVCMOS33 [get_ports lcd_cs] + +set_property PACKAGE_PIN C17 [get_ports ser0_tx] +set_property IOSTANDARD LVCMOS33 [get_ports ser0_tx] +set_property PACKAGE_PIN D18 [get_ports ser0_rx] +set_property IOSTANDARD LVCMOS33 [get_ports ser0_rx] + +set_property PULLTYPE PULLUP [get_ports user_sw[*]] +set_property PULLTYPE PULLUP [get_ports nav_sw[*]] + + +set_output_delay -clock mainclk 0.000 [get_ports userled] + +set_property PACKAGE_PIN P15 [get_ports mainclk] +set_property IOSTANDARD LVCMOS33 [get_ports mainclk] + +set_property CFGBVS VCCO [current_design] +set_property CONFIG_VOLTAGE 3.3 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] + +set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_i] diff --git a/ibex_demo_system.core b/ibex_demo_system.core index 667bbb8b..2e6c6e4d 100644 --- a/ibex_demo_system.core +++ b/ibex_demo_system.core @@ -33,6 +33,15 @@ filesets: - rtl/fpga/top_cw312a35.sv file_type: systemVerilogSource + files_sonata: + depend: + - lowrisc:ibex:rv_timer + - lowrisc:ibex:fpga_xilinx_shared + files: + - rtl/fpga/top_sonata.sv + - rtl/fpga/clkgen_sonata.sv + file_type: systemVerilogSource + files_verilator: depend: - lowrisc:ibex:sim_shared @@ -60,7 +69,10 @@ filesets: - data/pins_cw312a35.xdc file_type: xdc - + files_constraints_sonata: + files: + - data/pins_sonata.xdc + file_type: xdc parameters: # XXX: This parameter needs to be absolute, or relative to the *.runs/synth_1 @@ -131,6 +143,19 @@ targets: - PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx flags: use_bscane_tap: true + synth_sonata: + <<: *default_target + default_tool: vivado + filesets_append: + - files_sonata + - files_constraints_sonata + toplevel: top_sonata + tools: + vivado: + part: "xc7a50tcsg324-1" + parameters: + - SRAMInitFile + - PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx sim: <<: *default_target diff --git a/rtl/fpga/clkgen_sonata.sv b/rtl/fpga/clkgen_sonata.sv new file mode 100644 index 00000000..d216f67f --- /dev/null +++ b/rtl/fpga/clkgen_sonata.sv @@ -0,0 +1,83 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module clkgen_sonata ( + input IO_CLK, + output IO_CLK_BUF, + input IO_RST_N, + output clk_sys, + output rst_sys_n +); + logic locked_pll; + logic io_clk_buf; + logic clk_50_buf; + logic clk_50_unbuf; + logic clk_fb_buf; + logic clk_fb_unbuf; + + // input buffer + IBUF io_clk_ibuf( + .I (IO_CLK), + .O (io_clk_buf) + ); + + PLLE2_ADV #( + .BANDWIDTH ("OPTIMIZED"), + .COMPENSATION ("ZHOLD"), + .STARTUP_WAIT ("FALSE"), + .DIVCLK_DIVIDE (1), + .CLKFBOUT_MULT (34), + .CLKFBOUT_PHASE (0.000), + .CLKOUT0_DIVIDE (17), + .CLKOUT0_PHASE (0.000), + .CLKOUT0_DUTY_CYCLE (0.500), + .CLKIN1_PERIOD (40.000) + ) pll ( + .CLKFBOUT (clk_fb_unbuf), + .CLKOUT0 (clk_50_unbuf), + .CLKOUT1 (), + .CLKOUT2 (), + .CLKOUT3 (), + .CLKOUT4 (), + .CLKOUT5 (), + // Input clock control + .CLKFBIN (clk_fb_buf), + .CLKIN1 (io_clk_buf), + .CLKIN2 (1'b0), + // Tied to always select the primary input clock + .CLKINSEL (1'b1), + // Ports for dynamic reconfiguration + .DADDR (7'h0), + .DCLK (1'b0), + .DEN (1'b0), + .DI (16'h0), + .DO (), + .DRDY (), + .DWE (1'b0), + // Other control and status signals + .LOCKED (locked_pll), + .PWRDWN (1'b0), + // Do not reset PLL on external reset, otherwise ILA disconnects at a reset + .RST (1'b0)); + + // output buffering + BUFG clk_fb_bufg ( + .I (clk_fb_unbuf), + .O (clk_fb_buf) + ); + + BUFG clk_50_bufg ( + .I (clk_50_unbuf), + .O (clk_50_buf) + ); + + assign IO_CLK_BUF = io_clk_buf; + + // outputs + // clock + assign clk_sys = clk_50_buf; + + // reset + assign rst_sys_n = locked_pll & IO_RST_N; +endmodule diff --git a/rtl/fpga/top_sonata.sv b/rtl/fpga/top_sonata.sv new file mode 100644 index 00000000..8b4e76d4 --- /dev/null +++ b/rtl/fpga/top_sonata.sv @@ -0,0 +1,105 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Ibex demo system top level for the Sonata board +module top_sonata ( + input mainclk, + + output logic [7:0] userled, + output logic led_bootok, + output logic led_halted, + output logic led_cheri, + output logic led_legacy, + output logic [8:0] cherrierr, + + input logic [4:0] nav_sw, + input logic [7:0] user_sw, + + output logic lcd_rst, + output logic lcd_dc, + output logic lcd_copi, + output logic lcd_clk, + output logic lcd_cs, + + output logic ser0_tx, + input logic ser0_rx, + + input logic tck_i, + input logic tms_i, + input logic td_i, + output logic td_o +); + parameter SRAMInitFile = ""; + + logic top_rst_n; + logic mainclk_buf; + logic clk_sys, rst_sys_n; + logic [7:0] reset_counter; + + logic [4:0] nav_sw_n; + logic [7:0] user_sw_n; + + initial begin + reset_counter = 0; + end + + always_ff @(posedge mainclk_buf) begin + if (reset_counter != 8'hff) begin + reset_counter <= reset_counter + 8'd1; + end + end + + assign top_rst_n = reset_counter < 8'd5 ? 1'b1 : + reset_counter < 8'd200 ? 1'b0 : + 1'b1; + + assign led_bootok = 1'b1; + + // Switch inputs have pull-ups and switches pull to ground when on. Invert here so CPU sees 1 for + // on and 0 for off. + assign nav_sw_n = ~nav_sw; + assign user_sw_n = ~user_sw; + + // No LCD backlight FPGA IO on v0.2 board, so leave this unconnected + logic lcd_backlight; + + ibex_demo_system #( + .GpiWidth(13), + .GpoWidth(12), + .PwmWidth(12), + .SRAMInitFile(SRAMInitFile) + ) u_ibex_demo_system ( + //input + .clk_sys_i(clk_sys), + .rst_sys_ni(rst_sys_n), + + .gp_i({user_sw_n, nav_sw_n[4:0]}), + .gp_o({userled, lcd_backlight, lcd_dc, lcd_rst, lcd_cs}), + + .uart_rx_i(ser0_rx), + .uart_tx_o(ser0_tx), + + .pwm_o({cherrierr, led_legacy, led_cheri, led_halted}), + + .spi_rx_i(1'b0), + .spi_tx_o(lcd_copi), + .spi_sck_o(lcd_clk), + + .trst_ni(rst_sys_n), + .tms_i, + .tck_i, + .td_i, + .td_o + ); + + // Produce 50 MHz system clock from 25 MHz Sonata board clock + clkgen_sonata clkgen( + .IO_CLK(mainclk), + .IO_CLK_BUF(mainclk_buf), + .IO_RST_N(top_rst_n), + .clk_sys, + .rst_sys_n + ); + +endmodule diff --git a/util/sonata-openocd-cfg.tcl b/util/sonata-openocd-cfg.tcl new file mode 100644 index 00000000..811b8c2b --- /dev/null +++ b/util/sonata-openocd-cfg.tcl @@ -0,0 +1,33 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +adapter driver ftdi +transport select jtag + +ftdi_vid_pid 0x0403 0x6011 +ftdi_channel 1 +ftdi_layout_init 0x0088 0x008b +reset_config none + +# Configure JTAG chain and the target processor +set _CHIPNAME riscv + +# Ibex Demo System JTAG IDCODE +set _EXPECTED_ID 0x11001CDF + +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_EXPECTED_ID -ignore-version +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME + +adapter speed 10000 + +riscv set_prefer_sba on +gdb_report_data_abort enable +gdb_report_register_access_error enable +gdb_breakpoint_override hard + +reset_config none + +init +halt