Skip to content

Commit

Permalink
Get simple blinky firmware running on Icebreaker!
Browse files Browse the repository at this point in the history
Required some tweaks to the design to get the size down:
- Configure Ibex to use FPGA-optimized register file (implements RF as
block RAM)
- Configure Ibex to remove optional performance counters
- Reduce size of RAM
- Reduce # of outstanding requests for TLUL RAM adapter
- Modify uart_core.sv to reduce size of UART FIFOs
  • Loading branch information
nmoroze committed May 26, 2021
1 parent c840804 commit a94be4c
Show file tree
Hide file tree
Showing 10 changed files with 2,719 additions and 34 deletions.
7 changes: 7 additions & 0 deletions .gitignore
@@ -1,2 +1,9 @@
zerosoc.v
zerosoc.vcd

# SC build dir
build/

# FPGA build outputs
*.asc
*.bit
15 changes: 13 additions & 2 deletions Makefile
Expand Up @@ -39,14 +39,16 @@ SV_SOURCES += hw/opentitan/hw/vendor/lowrisc_ibex/rtl/ibex_multdiv_fast.sv
SV_SOURCES += hw/opentitan/hw/vendor/lowrisc_ibex/rtl/ibex_prefetch_buffer.sv
SV_SOURCES += hw/opentitan/hw/vendor/lowrisc_ibex/rtl/ibex_pmp.sv
SV_SOURCES += hw/opentitan/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_ff.sv
SV_SOURCES += hw/opentitan/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_fpga.sv
SV_SOURCES += hw/opentitan/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv
SV_SOURCES += hw/opentitan/hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv

SV_SOURCES += hw/opentitan/hw/ip/uart/rtl/uart_reg_pkg.sv
SV_SOURCES += hw/opentitan/hw/ip/uart/rtl/uart_reg_top.sv
SV_SOURCES += hw/opentitan/hw/ip/uart/rtl/uart_rx.sv
SV_SOURCES += hw/opentitan/hw/ip/uart/rtl/uart_tx.sv
SV_SOURCES += hw/opentitan/hw/ip/uart/rtl/uart_core.sv
# TODO: upstream changes and switch back to OpenTitan UART
SV_SOURCES += hw/uart_core.sv
SV_SOURCES += hw/opentitan/hw/ip/uart/rtl/uart.sv

SV_SOURCES += hw/opentitan/hw/ip/gpio/rtl/gpio_reg_pkg.sv
Expand Down Expand Up @@ -89,7 +91,10 @@ SV_SOURCES += hw/xbar.sv
SV_SOURCES += hw/zerosoc.sv

.PHONY: all
all: zerosoc.v
all: zerosoc.bit

.PHONY: check
check: zerosoc.v
yosys -p 'read_verilog -sv zerosoc.v; hierarchy -check'

.PHONY: clean
Expand All @@ -99,6 +104,12 @@ clean:
zerosoc.v: $(SV_SOURCES)
sv2v -I=hw/opentitan/hw/ip/prim/rtl/ -I=hw/opentitan/hw/dv/sv/dv_utils/ -DSYNTHESIS $^ > $@

build/top_icebreaker/job1/export/outputs/top_icebreaker.bit: hw/top_icebreaker.v zerosoc.v
python3 build.py

zerosoc.bit: build/top_icebreaker/job1/export/outputs/top_icebreaker.bit
cp $< $@

# Simulation

sim/zerosoc_tb.out: sim/zerosoc_tb.v zerosoc.v
Expand Down
12 changes: 6 additions & 6 deletions build.py
@@ -1,13 +1,13 @@
import siliconcompiler as sc

source = 'soc.v'
# TODO: add switch to select fpga vs asic build

chip = sc.Chip()
chip.add('source', source)
chip.add('design', 'soc')
chip.set('target', 'freepdk45')
chip.set('asic', 'diesize', "0 0 100.13 100.8")
chip.set('asic', 'coresize', "10.07 11.2 90.25 91")
chip.add('source', 'zerosoc.v')
chip.add('source', 'hw/top_icebreaker.v')
chip.add('design', 'top_icebreaker')
chip.set('target', 'ice40_nextpnr')
chip.set('constraint', 'data/icebreaker.pcf')
chip.set_jobid()

chip.target()
Expand Down
66 changes: 66 additions & 0 deletions data/icebreaker.pcf
@@ -0,0 +1,66 @@
## Source: https://github.com/icebreaker-fpga/icebreaker-examples/blob/master/icebreaker.pcf

# 12 MHz clock
set_io -nowarn CLK 35

# RS232
set_io -nowarn RX 6
set_io -nowarn TX 9

# LEDs and Button
set_io -nowarn BTN_N 10
set_io -nowarn LEDR_N 11
set_io -nowarn LEDG_N 37

# RGB LED Driver
set_io -nowarn LED_RED_N 39
set_io -nowarn LED_GRN_N 40
set_io -nowarn LED_BLU_N 41

# SPI Flash
set_io -nowarn FLASH_SCK 15
set_io -nowarn FLASH_SSB 16
set_io -nowarn FLASH_IO0 14
set_io -nowarn FLASH_IO1 17
set_io -nowarn FLASH_IO2 12
set_io -nowarn FLASH_IO3 13

# PMOD 1A
set_io -nowarn P1A1 4
set_io -nowarn P1A2 2
set_io -nowarn P1A3 47
set_io -nowarn P1A4 45
set_io -nowarn P1A7 3
set_io -nowarn P1A8 48
set_io -nowarn P1A9 46
set_io -nowarn P1A10 44

# PMOD 1B
set_io -nowarn P1B1 43
set_io -nowarn P1B2 38
set_io -nowarn P1B3 34
set_io -nowarn P1B4 31
set_io -nowarn P1B7 42
set_io -nowarn P1B8 36
set_io -nowarn P1B9 32
set_io -nowarn P1B10 28

# PMOD 2
set_io -nowarn P2_1 27
set_io -nowarn P2_2 25
set_io -nowarn P2_3 21
set_io -nowarn P2_4 19
set_io -nowarn P2_7 26
set_io -nowarn P2_8 23
set_io -nowarn P2_9 20
set_io -nowarn P2_10 18

# LEDs and Buttons (PMOD 2)
set_io -nowarn LED1 26
set_io -nowarn LED2 27
set_io -nowarn LED3 25
set_io -nowarn LED4 23
set_io -nowarn LED5 21
set_io -nowarn BTN1 20
set_io -nowarn BTN2 19
set_io -nowarn BTN3 18
31 changes: 18 additions & 13 deletions hw/prim/prim_clock_gating.sv
Expand Up @@ -8,6 +8,9 @@
`define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
`endif

// TODO: create icebreaker prim library
// can implement clock gate using SB_GB_IO primitive

// This is to prevent AscentLint warnings in the generated
// abstract prim wrapper. These warnings occur due to the .*
// use. TODO: we may want to move these inline waivers
Expand All @@ -27,19 +30,21 @@ module prim_clock_gating
);
parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;

if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
prim_xilinx_clock_gating #(
.NoFpgaGate(NoFpgaGate)
) u_impl_xilinx (
.*
);
end else begin : gen_generic
prim_generic_clock_gating #(
.NoFpgaGate(NoFpgaGate)
) u_impl_generic (
.*
);
end
assign clk_o = clk_i;

// if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
// prim_xilinx_clock_gating #(
// .NoFpgaGate(NoFpgaGate)
// ) u_impl_xilinx (
// .*
// );
// end else begin : gen_generic
// prim_generic_clock_gating #(
// .NoFpgaGate(NoFpgaGate)
// ) u_impl_generic (
// .*
// );
// end

endmodule
//ri lint_check_on OUTPUT_NOT_DRIVEN INPUT_NOT_READ
54 changes: 54 additions & 0 deletions hw/top_icebreaker.v
@@ -0,0 +1,54 @@
module top_icebreaker (
input CLK,
input BTN_N,

input RX,
output TX,

input BTN1,
input BTN2,
input BTN3,

output LED1,
output LED2,
output LED3,
output LED4,
output LED5
);

wire clk_6mhz;

SB_HFOSC #(
.CLKHF_DIV("0b11") // 6mhz
) clock_gen (
.CLKHFPU(1'b1),
.CLKHFEN(1'b1),
.CLKHF(clk_6mhz)
);

wire [2:0] gpio_in;
assign gpio_in[0] = BTN1;
assign gpio_in[1] = BTN2;
assign gpio_in[2] = BTN3;

wire [31:0] gpio_out;
assign LED1 = gpio_out[0];
assign LED2 = gpio_out[1];
assign LED3 = gpio_out[2];
assign LED4 = gpio_out[3];
assign LED5 = gpio_out[4];

zerosoc soc(
.clk_i(clk_6mhz),
.rst_ni(BTN_N),

.uart_rx_i(RX),
.uart_tx_o(TX),
.uart_tx_en_o(),

.gpio_i({29'b0, gpio_in}),
.gpio_o(gpio_out),
.gpio_en_o()
);

endmodule

0 comments on commit a94be4c

Please sign in to comment.