Skip to content

Commit

Permalink
Create simple SoC example with simulation, firmware and hello world e…
Browse files Browse the repository at this point in the history
…xample

Internal-tag: [#57628]
Signed-off-by: Krzysztof Obłonczek <koblonczek@antmicro.com>
  • Loading branch information
Krzysztof Obłonczek authored and rw1nkler committed May 15, 2024
1 parent 8b272e3 commit bc0ab4e
Show file tree
Hide file tree
Showing 15 changed files with 7,955 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/scripts/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
set -e

ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")"/../.. &>/dev/null && pwd)
EXAMPLES=(hdmi inout pwm)
EXAMPLES=(hdmi inout pwm soc)

begin_command_group() {
if [[ -n "${GITHUB_WORKFLOW:-}" ]]; then
Expand Down
56 changes: 56 additions & 0 deletions examples/soc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright (c) 2024 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0

IPCORE_SOURCES = sources/mem.v sources/VexRiscv.v sources/crg.v sources/wb_uart.v sources/wb_interconnect.v
IPCORE_YAMLS = ipcores/gen_mem.yaml ipcores/gen_VexRiscv.yaml ipcores/gen_crg.yaml ipcores/gen_wb_uart.yaml ipcores/gen_wb_interconnect.yaml

all: upload

build:
mkdir build

ipcores:
mkdir ipcores

$(IPCORE_YAMLS) &: $(IPCORE_SOURCES) | ipcores
topwrap parse -d ipcores --iface-deduce $(IPCORE_SOURCES)

build/simple_soc.v: $(IPCORE_YAMLS) project.yaml | build
topwrap build -b build --design project.yaml --sources sources

build/helloworld.bin: helloworld.asm | build
riscv64-unknown-elf-as -mabi=ilp32 -march=rv32i -o $@ $<

build/bios.bin: build/helloworld.bin | build
riscv64-unknown-elf-objcopy -O binary $< $@

build/bios.init: build/bios.bin | build
hexdump -v -e '1/4 "%08X\n"' $< > $@

build/simple_soc.bit: build/bios.init simple_soc.tcl $(IPCORE_SOURCES) build/simple_soc.v | build
vivado -mode batch -source simple_soc.tcl


generate: build/simple_soc.v

build-sim: build/simple_soc.v
$(MAKE) -fverilator.mk

sim: build-sim build/bios.init obj_dir/Vsimple_soc
obj_dir/Vsimple_soc
vcd2fst build/dump.vcd build/dump.fst

bitstream: build/simple_soc.bit

upload: build/simple_soc.bit
openFPGALoader --board antmicro_lpddr4_tester $<

clean:
rm -rf ipcores
rm -rf build
rm -rf obj_dir
# vivado data
rm -rf .Xil simple_soc.hw simple_soc.cache simple_soc.ip_user_files simple_soc.xpr
rm -f vivado* usage_statistics_webtalk*

.PHONY: all generate build-sim sim bitstream upload clean
40 changes: 40 additions & 0 deletions examples/soc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Topwrap SoC example setup

Copyright (c) 2024 [Antmicro](https://antmicro.com)

This is an example on how to use [Topwrap](https://github.com/antmicro/topwrap) to build a synthesizable SoC design.
The SoC contains a VexRiscv core, data and instruction memory, UART and interconnect that ties all components together.

## Install required dependencies

```
sudo apt install git make g++ ninja-build gcc-riscv64-unknown-elf bsdextrautils
```

To run the simulation you also need:
- verilator

To create and load bitstream you also need:
- vivado (preferably version 2020.2)
- openFPGALoader ([this branch](https://github.com/antmicro/openFPGALoader/tree/antmicro-ddr-tester-boards))

## Generate HDL sources

<!-- name="generate" -->
```
make generate
```

## Build and run simulation

```
make sim
```

Expected waveform generated by the simulation is shown in `expected-waveform.svg`.

## Generate bitstream

```
make bitstream
```
4 changes: 4 additions & 0 deletions examples/soc/expected-waveform.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions examples/soc/helloworld.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (c) 2024 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0

loop:
li a0, 0x68
jal x1, write_char
li a0, 0x65
jal x1, write_char
li a0, 0x6C
jal x1, write_char
li a0, 0x6C
jal x1, write_char
li a0, 0x6F
jal x1, write_char
li a0, 0x20
jal x1, write_char
li a0, 0x77
jal x1, write_char
li a0, 0x6F
jal x1, write_char
li a0, 0x72
jal x1, write_char
li a0, 0x6C
jal x1, write_char
li a0, 0x64
jal x1, write_char
li a0, 0x0D
jal x1, write_char
li a0, 0x0A
jal x1, write_char
j loop

write_char:
li t0, 0xF0000000 # base UART CSR address
wait:
lw t1, 0x4(t0) # load TX_FULL register
bne t1, x0, wait # check if TX fifo not full
sw a0, 0x0(t0) # store character
ret
70 changes: 70 additions & 0 deletions examples/soc/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright (c) 2024 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0

ips:
vexriscv:
file: ipcores/gen_VexRiscv.yaml
module: VexRiscv
wb_ram_data:
file: ipcores/gen_mem.yaml
module: mem
wb_ram_instr:
file: ipcores/gen_mem.yaml
module: mem
crg:
file: ipcores/gen_crg.yaml
module: crg
wb_uart:
file: ipcores/gen_wb_uart.yaml
module: wb_uart
interconnect:
file: ipcores/gen_wb_interconnect.yaml
module: wb_interconnect

design:
name: simple_soc
parameters:
wb_ram_data:
depth: 0x1000
wb_ram_instr:
depth: 0xA000
memfile: "build/bios.init"
ports:
wb_ram_data:
sys_clk: clk100
sys_rst: [crg, sys_rst]
wb_ram_instr:
sys_clk: clk100
sys_rst: [crg, sys_rst]
crg:
clk100: clk100
vexriscv:
clk: clk100
reset: [crg, sys_rst]
softwareInterrupt: 0
externalInterruptArray: 0
timerInterrupt: 0
externalResetVector: 0x00000000
wb_uart:
sys_clk: clk100
sys_rst: [crg, sys_rst]
serial1_tx: serial_tx
serial1_rx: serial_rx
interconnect:
clk: clk100
rst: [crg, sys_rst]
interfaces:
interconnect:
wb_uart_csr_wishbone: [wb_uart, csr_wishbone]
wb_ram_instr_mem_bus: [wb_ram_instr, mem_bus]
wb_ram_data_mem_bus: [wb_ram_data, mem_bus]
vexriscv_iBusWishbone: [vexriscv, iBusWishbone]
vexriscv_dBusWishbone: [vexriscv, dBusWishbone]

external:
ports:
in:
- clk100
- serial_rx
out:
- serial_tx
39 changes: 39 additions & 0 deletions examples/soc/sim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2024 Antmicro <www.antmicro.com>
// SPDX-License-Identifier: Apache-2.0

#include <memory>

#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

#include <verilated.h>

#include "Vsimple_soc.h"
#include "verilated_vcd_c.h"

int main(int argc, char** argv) {
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
contextp->debug(0);
contextp->randReset(2);
contextp->traceEverOn(true);
contextp->commandArgs(argc, argv);

const std::unique_ptr<Vsimple_soc> soc{new Vsimple_soc{contextp.get(), "simple_soc"}};
const std::unique_ptr<VerilatedVcdC> tfp{new VerilatedVcdC};
soc->trace(tfp.get(), 99);
tfp->open("build/dump.vcd");

soc->clk100 = 0;
while (contextp->time() < 225000) {
contextp->timeInc(1);
soc->clk100 = !soc->clk100;
soc->eval();
tfp->dump(contextp->time());
}

soc->final();
tfp->close();
return 0;
}
71 changes: 71 additions & 0 deletions examples/soc/simple_soc.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright (c) 2024 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0

# Create Project

create_project -force -name simple_soc -part xc7k70tfbg484-3
set_msg_config -id {Common 17-55} -new_severity {Warning}

# Add Sources

read_verilog {sources/crg.v}
read_verilog {sources/mem.v}
read_verilog {sources/VexRiscv.v}
read_verilog {sources/wb_interconnect.v}
read_verilog {sources/wb_uart.v}
read_verilog {build/simple_soc.v}

# Add constraints

read_xdc simple_soc.xdc
set_property PROCESSING_ORDER EARLY [get_files simple_soc.xdc]

# Synthesis

synth_design -directive default -top simple_soc -part xc7k70tfbg484-3

# Synthesis report

report_timing_summary -file build/top_timing_synth.rpt
report_utilization -hierarchical -file build/top_utilization_hierarchical_synth.rpt
report_utilization -file build/top_utilization_synth.rpt

# Optimize design

opt_design -directive default

# Placement

place_design -directive default

# Placement report

report_utilization -hierarchical -file build/top_utilization_hierarchical_place.rpt
report_utilization -file build/top_utilization_place.rpt
report_io -file build/top_io.rpt
report_control_sets -verbose -file build/top_control_sets.rpt
report_clock_utilization -file build/top_clock_utilization.rpt

# Routing

route_design -directive default
phys_opt_design -directive default
write_checkpoint -force build/top_route.dcp

# Routing report

report_timing_summary -no_header -no_detailed_paths
report_route_status -file build/top_route_status.rpt
report_drc -file build/top_drc.rpt
report_timing_summary -datasheet -max_paths 10 -file build/top_timing.rpt
report_power -file build/top_power.rpt
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]

# Bitstream generation

write_bitstream -force build/simple_soc.bit
write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit "up 0x0 build/simple_soc.bit" -file build/simple_soc.bin

# End

quit
36 changes: 36 additions & 0 deletions examples/soc/simple_soc.xdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) 2024 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0

################################################################################
# IO constraints
################################################################################
# clk100:0
set_property LOC L19 [get_ports {clk100}]
set_property IOSTANDARD LVCMOS33 [get_ports {clk100}]

# serial:1.tx
set_property LOC AA20 [get_ports {serial_tx}]
set_property IOSTANDARD LVCMOS33 [get_ports {serial_tx}]

# serial:1.rx
set_property LOC AB20 [get_ports {serial_rx}]
set_property IOSTANDARD LVCMOS33 [get_ports {serial_rx}]

###############################################################################
# Clock constraints
################################################################################
create_clock -name clk100 -period 10.0 [get_ports clk100]

################################################################################
# False path constraints
################################################################################
set_false_path -quiet -to [get_cells -hierarchical -filter { mr_ff == TRUE }]

set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]

set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]

set_max_delay -quiet -through [get_pins -filter {REF_PIN_NAME == Q} -of_objects [get_cells -hierarchical -filter {slow_ff == TRUE}]] 250

set_max_delay -quiet -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {slow_in == TRUE}]] 250

Loading

0 comments on commit bc0ab4e

Please sign in to comment.