Skip to content

Commit

Permalink
Add support for Sonata PCB
Browse files Browse the repository at this point in the history
This commit assumes revision 0.2 of the board. It adds a pin file, a top
level module, a clock generator and the appropriate changes to the core
file. It also updates the getting started guide to use the Sonata PCB by
default.

This commit is derived from a commit in the demo system:
lowRISC/ibex-demo-system@d9ec0d0
With the following changes:
- Remove the JTAG pins from the top and the XDC file since Sonata does
not have a debug module yet.
- Rename the pins to match the names in the PCB documentation.
  • Loading branch information
marnovandermaas committed Feb 2, 2024
1 parent f640161 commit d3af672
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 6 deletions.
78 changes: 78 additions & 0 deletions data/pins_sonata.xdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
## Copyright lowRISC contributors.
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
## SPDX-License-Identifier: Apache-2.0

# Using the names in the PCB design, they should match this file with a case-insensitive search:
# https://github.com/newaetech/sonata-pcb/tree/main

## Clocks
create_clock -period 40.000 -name mainClk -waveform {0.000 20.000} [get_ports mainClk]

set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports mainClk];

## Reset
set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports {nrst}];

## General purpose LEDs
set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports {usrLed[0]}];
set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports {usrLed[1]}];
set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports {usrLed[2]}];
set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports {usrLed[3]}];
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports {usrLed[4]}];
set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports {usrLed[5]}];
set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports {usrLed[6]}];
set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports {usrLed[7]}];

set_output_delay -clock mainClk 0.000 [get_ports usrLed]

## Switch and button input
set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports {usrSw[0]}];
set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports {usrSw[1]}];
set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports {usrSw[2]}];
set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports {usrSw[3]}];
set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports {usrSw[4]}];
set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports {usrSw[5]}];
set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports {usrSw[6]}];
set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports {usrSw[7]}];
set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS18 } [get_ports {navSw[0]}];
set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS18 } [get_ports {navSw[1]}];
set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS18 } [get_ports {navSw[2]}];
set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS18 } [get_ports {navSw[3]}];
set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS18 } [get_ports {navSw[4]}];

## CHERI error LEDs
set_property -dict { PACKAGE_PIN K6 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[0]}];
set_property -dict { PACKAGE_PIN L1 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[1]}];
set_property -dict { PACKAGE_PIN M1 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[2]}];
set_property -dict { PACKAGE_PIN K3 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[3]}];
set_property -dict { PACKAGE_PIN L3 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[4]}];
set_property -dict { PACKAGE_PIN N2 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[5]}];
set_property -dict { PACKAGE_PIN N1 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[6]}];
set_property -dict { PACKAGE_PIN M3 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[7]}];
set_property -dict { PACKAGE_PIN M2 IOSTANDARD LVCMOS33 } [get_ports {cheriErr[8]}];

## Status LEDs
set_property -dict { PACKAGE_PIN K5 IOSTANDARD LVCMOS33 } [get_ports led_legacy];
set_property -dict { PACKAGE_PIN L4 IOSTANDARD LVCMOS33 } [get_ports led_cheri];
set_property -dict { PACKAGE_PIN L6 IOSTANDARD LVCMOS33 } [get_ports led_halted];
set_property -dict { PACKAGE_PIN L5 IOSTANDARD LVCMOS33 } [get_ports led_bootok];

## LCD display
set_property -dict { PACKAGE_PIN R6 IOSTANDARD LVCMOS33 } [get_ports lcd_rst];
set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports lcd_dc];
set_property -dict { PACKAGE_PIN R3 IOSTANDARD LVCMOS33 } [get_ports lcd_copi];
set_property -dict { PACKAGE_PIN R5 IOSTANDARD LVCMOS33 } [get_ports lcd_clk];
set_property -dict { PACKAGE_PIN P5 IOSTANDARD LVCMOS33 } [get_ports lcd_cs];

## UART
set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports ser0_tx];
set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports ser0_rx];

## Switches
set_property PULLTYPE PULLUP [get_ports usrSw[*]]
set_property PULLTYPE PULLUP [get_ports navSw[*]]

## Voltage
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
6 changes: 5 additions & 1 deletion doc/guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,13 @@ Then run this command:
fusesoc --cores-root=. run --target=synth --setup --build lowrisc:sonata:system
```

For the Arty A7 use the `synth_artya7` target.

### Programming

Programming the FPGA:
```sh
openFPGALoader -b arty_a7_35t build/lowrisc_sonata_system_0/synth-vivado/lowrisc_sonata_system_0.bit
openFPGALoader -c ft4232 build/lowrisc_sonata_system_0/synth-vivado/lowrisc_sonata_system_0.bit
```

For the Arty A7 use `-b arty_a7_35t` instead of `-c ft4232`.
83 changes: 83 additions & 0 deletions rtl/fpga/clkgen_sonata.sv
Original file line number Diff line number Diff line change
@@ -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
94 changes: 94 additions & 0 deletions rtl/fpga/top_sonata.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// Sonata system top level for the Sonata PCB
module top_sonata (
input logic mainClk,
input logic nrst,

output logic [7:0] usrLed,
output logic led_bootok,
output logic led_halted,
output logic led_cheri,
output logic led_legacy,
output logic [8:0] cheriErr,

input logic [4:0] navSw,
input logic [7:0] usrSw,

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
);
parameter SRAMInitFile = "";

logic top_rst_n;
logic main_clk_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 main_clk_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 :
nrst ;

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 = ~navSw;
assign user_sw_n = ~usrSw;

// No LCD backlight FPGA IO on v0.2 board, so leave this unconnected.
logic lcd_backlight;

sonata_system #(
.GpiWidth ( 13 ),
.GpoWidth ( 12 ),
.PwmWidth ( 12 ),
.SRAMInitFile( SRAMInitFile )
) u_sonata_system (
.clk_sys_i (clk_sys),
.rst_sys_ni(rst_sys_n),

.gp_i({user_sw_n, nav_sw_n}),
.gp_o({usrLed, lcd_backlight, lcd_dc, lcd_rst, lcd_cs}),

.uart_rx_i(ser0_rx),
.uart_tx_o(ser0_tx),

.pwm_o({CheriErr, led_legacy, led_cheri, led_halted}),

.spi_rx_i (1'b0),
.spi_tx_o (lcd_copi),
.spi_sck_o(lcd_clk)
);

// Produce 50 MHz system clock from 25 MHz Sonata board clock.
clkgen_sonata clkgen(
.IO_CLK (mainClk),
.IO_CLK_BUF(main_clk_buf),
.IO_RST_N (top_rst_n),
.clk_sys,
.rst_sys_n
);

endmodule
39 changes: 34 additions & 5 deletions sonata.core
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ filesets:
depend:
- lowrisc:sonata:design

files_xilinx:
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_artya7:
depend:
- lowrisc:ibex:rv_timer
- lowrisc:ibex:fpga_xilinx_shared
Expand All @@ -29,7 +38,12 @@ filesets:
- dv/verilator/sonata_system_main.cc: { file_type: cppSource }
- dv/verilator/sonata_verilator_lint.vlt: { file_type: vlt }

files_constraints:
files_constraints_sonata:
files:
- data/pins_sonata.xdc
file_type: xdc

files_constraints_artya7:
files:
- data/pins_artya7.xdc
file_type: xdc
Expand Down Expand Up @@ -57,16 +71,31 @@ targets:
default: &default_target
filesets:
- files_rtl

synth:
<<: *default_target
default_tool: vivado
filesets_append:
- files_xilinx
- files_constraints
- files_sonata
- files_constraints_sonata
toplevel: top_sonata
tools:
vivado:
part: "xc7a50tcsg324-1" # Artix-7 50T
parameters:
- SRAMInitFile
- PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx

synth_artya7:
<<: *default_target
default_tool: vivado
filesets_append:
- files_artya7
- files_constraints_artya7
toplevel: top_artya7
tools:
vivado:
part: "xc7a35tcsg324-1" # Default to Arty A7-35
part: "xc7a35tcsg324-1" # Arty A7-35T
parameters:
- SRAMInitFile
- PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx
Expand Down

0 comments on commit d3af672

Please sign in to comment.