aboutsummaryrefslogtreecommitdiffstats
path: root/picosoc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-08-18 20:17:21 +0200
committerClifford Wolf <clifford@clifford.at>2018-08-18 20:17:21 +0200
commit1afe3af452212b424a96d2e0d1b89aab0259e50e (patch)
treef559ab70953809400e1bf90c2dc382d19926c25e /picosoc
parentb634224ccb9581ffde6f7ecde4553f743c03588c (diff)
downloadpicorv32-1afe3af452212b424a96d2e0d1b89aab0259e50e.tar.gz
picorv32-1afe3af452212b424a96d2e0d1b89aab0259e50e.zip
Add PicoSoC IceBreaker demo
Signed-off-by: Clifford Wolf <clifford@clifford.at>
Diffstat (limited to 'picosoc')
-rw-r--r--picosoc/.gitignore8
-rw-r--r--picosoc/Makefile43
-rw-r--r--picosoc/firmware.c2
-rw-r--r--picosoc/icebreaker.pcf25
-rw-r--r--picosoc/icebreaker.v140
-rw-r--r--picosoc/icebreaker_tb.v117
-rw-r--r--picosoc/picosoc.v14
7 files changed, 341 insertions, 8 deletions
diff --git a/picosoc/.gitignore b/picosoc/.gitignore
index 4a2e42e..c8e45ae 100644
--- a/picosoc/.gitignore
+++ b/picosoc/.gitignore
@@ -11,5 +11,13 @@
/hx8kdemo_syn.v
/hx8kdemo_syn_tb.vvp
/hx8kdemo_tb.vvp
+/icebreaker.asc
+/icebreaker.bin
+/icebreaker.json
+/icebreaker.log
+/icebreaker.rpt
+/icebreaker_syn.v
+/icebreaker_syn_tb.vvp
+/icebreaker_tb.vvp
/testbench.vcd
/cmos.log
diff --git a/picosoc/Makefile b/picosoc/Makefile
index 0faf167..3615f91 100644
--- a/picosoc/Makefile
+++ b/picosoc/Makefile
@@ -33,10 +33,44 @@ hx8kprog: hx8kdemo.bin firmware.bin
hx8kprog_fw: firmware.bin
iceprog -o 1M firmware.bin
+# ---- iCE40 IceBreaker Board ----
+
+icebsim: icebreaker_tb.vvp firmware.hex
+ vvp -N $<
+
+icebsynsim: icebreaker_syn_tb.vvp firmware.hex
+ vvp -N $<
+
+icebreaker.json: icebreaker.v spimemio.v simpleuart.v picosoc.v ../picorv32.v
+ yosys -ql icebreaker.log -p 'synth_ice40 -top icebreaker -json icebreaker.json' $^
+
+icebreaker_tb.vvp: icebreaker_tb.v icebreaker.v spimemio.v simpleuart.v picosoc.v ../picorv32.v spiflash.v
+ iverilog -s testbench -o $@ $^ `yosys-config --datdir/ice40/cells_sim.v`
+
+icebreaker_syn_tb.vvp: icebreaker_tb.v icebreaker_syn.v spiflash.v
+ iverilog -s testbench -o $@ $^ `yosys-config --datdir/ice40/cells_sim.v`
+
+icebreaker_syn.v: icebreaker.json
+ yosys -p 'read_json icebreaker.json; write_verilog icebreaker_syn.v'
+
+icebreaker.asc: icebreaker.pcf icebreaker.json
+ nextpnr-ice40 --freq 13 --up5k --asc icebreaker.asc --pcf icebreaker.pcf --json icebreaker.json
+
+icebreaker.bin: icebreaker.asc
+ icetime -d up5k -c 12 -mtr icebreaker.rpt icebreaker.asc
+ icepack icebreaker.asc icebreaker.bin
+
+icebprog: icebreaker.bin firmware.bin
+ iceprog icebreaker.bin
+ iceprog -o 1M firmware.bin
+
+icebprog_fw: firmware.bin
+ iceprog -o 1M firmware.bin
+
# ---- Example Firmware ----
firmware.elf: sections.lds start.s firmware.c
- riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf start.s firmware.c
+ riscv32-unknown-elf-gcc -march=rv32ic -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf start.s firmware.c
firmware.hex: firmware.elf
riscv32-unknown-elf-objcopy -O verilog firmware.elf firmware.hex
@@ -64,6 +98,9 @@ clean:
rm -f firmware.elf firmware.hex firmware.bin cmos.log
rm -f hx8kdemo.blif hx8kdemo.log hx8kdemo.asc hx8kdemo.rpt hx8kdemo.bin
rm -f hx8kdemo_syn.v hx8kdemo_syn_tb.vvp hx8kdemo_tb.vvp
+ rm -f icebreaker.json icebreaker.log icebreaker.asc icebreaker.rpt icebreaker.bin
+ rm -f icebreaker_syn.v icebreaker_syn_tb.vvp icebreaker_tb.vvp
-.PHONY: spiflash_tb hx8kprog hx8kprog_fw hx8ksim hx8ksynsim clean
-
+.PHONY: spiflash_tb clean
+.PHONY: hx8kprog hx8kprog_fw hx8ksim hx8ksynsim
+.PHONY: icebprog icebprog_fw icebsim icebsynsim
diff --git a/picosoc/firmware.c b/picosoc/firmware.c
index f1ffbd3..2db2588 100644
--- a/picosoc/firmware.c
+++ b/picosoc/firmware.c
@@ -32,7 +32,7 @@ void set_flash_qspi_flag()
{
uint8_t buffer[8];
-#if 0
+#if 1
uint32_t addr_cr1v = 0x800002;
// Read Any Register (RDAR 65h)
diff --git a/picosoc/icebreaker.pcf b/picosoc/icebreaker.pcf
new file mode 100644
index 0000000..86cf78e
--- /dev/null
+++ b/picosoc/icebreaker.pcf
@@ -0,0 +1,25 @@
+# 12 MHz clock
+set_io clk 35
+
+# RS232
+set_io ser_rx 6
+set_io ser_tx 9
+
+# SPI Flash
+set_io flash_clk 15
+set_io flash_csb 16
+set_io flash_io0 14
+set_io flash_io1 17
+set_io flash_io2 12
+set_io flash_io3 13
+
+# LEDs (PMOD 2)
+set_io led1 27
+set_io led2 25
+set_io led3 21
+set_io led4 23
+set_io led5 26
+
+# Onboard LEDs
+set_io ledr_n 11
+set_io ledg_n 37
diff --git a/picosoc/icebreaker.v b/picosoc/icebreaker.v
new file mode 100644
index 0000000..ef9b9ac
--- /dev/null
+++ b/picosoc/icebreaker.v
@@ -0,0 +1,140 @@
+/*
+ * PicoSoC - A simple example SoC using PicoRV32
+ *
+ * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+module icebreaker (
+ input clk,
+
+ output ser_tx,
+ input ser_rx,
+
+ output led1,
+ output led2,
+ output led3,
+ output led4,
+ output led5,
+
+ output ledr_n,
+ output ledg_n,
+
+ output flash_csb,
+ output flash_clk,
+ inout flash_io0,
+ inout flash_io1,
+ inout flash_io2,
+ inout flash_io3
+);
+ reg [5:0] reset_cnt = 0;
+ wire resetn = &reset_cnt;
+
+ always @(posedge clk) begin
+ reset_cnt <= reset_cnt + !resetn;
+ end
+
+ wire [7:0] leds;
+
+ assign led1 = leds[1];
+ assign led2 = leds[2];
+ assign led3 = leds[3];
+ assign led4 = leds[4];
+ assign led5 = leds[5];
+
+ assign ledr_n = !leds[6];
+ assign ledg_n = !leds[7];
+
+ wire flash_io0_oe, flash_io0_do, flash_io0_di;
+ wire flash_io1_oe, flash_io1_do, flash_io1_di;
+ wire flash_io2_oe, flash_io2_do, flash_io2_di;
+ wire flash_io3_oe, flash_io3_do, flash_io3_di;
+
+ SB_IO #(
+ .PIN_TYPE(6'b 1010_01),
+ .PULLUP(1'b 0)
+ ) flash_io_buf [3:0] (
+ .PACKAGE_PIN({flash_io3, flash_io2, flash_io1, flash_io0}),
+ .OUTPUT_ENABLE({flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe}),
+ .D_OUT_0({flash_io3_do, flash_io2_do, flash_io1_do, flash_io0_do}),
+ .D_IN_0({flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di})
+ );
+
+ wire iomem_valid;
+ reg iomem_ready;
+ wire [3:0] iomem_wstrb;
+ wire [31:0] iomem_addr;
+ wire [31:0] iomem_wdata;
+ reg [31:0] iomem_rdata;
+
+ reg [31:0] gpio;
+ assign leds = gpio;
+
+ always @(posedge clk) begin
+ if (!resetn) begin
+ gpio <= 0;
+ end else begin
+ iomem_ready <= 0;
+ if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 03) begin
+ iomem_ready <= 1;
+ iomem_rdata <= gpio;
+ if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
+ if (iomem_wstrb[1]) gpio[15: 8] <= iomem_wdata[15: 8];
+ if (iomem_wstrb[2]) gpio[23:16] <= iomem_wdata[23:16];
+ if (iomem_wstrb[3]) gpio[31:24] <= iomem_wdata[31:24];
+ end
+ end
+ end
+
+ picosoc #(
+ .BARREL_SHIFTER(0),
+ .ENABLE_MULDIV(0)
+ ) soc (
+ .clk (clk ),
+ .resetn (resetn ),
+
+ .ser_tx (ser_tx ),
+ .ser_rx (ser_rx ),
+
+ .flash_csb (flash_csb ),
+ .flash_clk (flash_clk ),
+
+ .flash_io0_oe (flash_io0_oe),
+ .flash_io1_oe (flash_io1_oe),
+ .flash_io2_oe (flash_io2_oe),
+ .flash_io3_oe (flash_io3_oe),
+
+ .flash_io0_do (flash_io0_do),
+ .flash_io1_do (flash_io1_do),
+ .flash_io2_do (flash_io2_do),
+ .flash_io3_do (flash_io3_do),
+
+ .flash_io0_di (flash_io0_di),
+ .flash_io1_di (flash_io1_di),
+ .flash_io2_di (flash_io2_di),
+ .flash_io3_di (flash_io3_di),
+
+ .irq_5 (1'b0 ),
+ .irq_6 (1'b0 ),
+ .irq_7 (1'b0 ),
+
+ .iomem_valid (iomem_valid ),
+ .iomem_ready (iomem_ready ),
+ .iomem_wstrb (iomem_wstrb ),
+ .iomem_addr (iomem_addr ),
+ .iomem_wdata (iomem_wdata ),
+ .iomem_rdata (iomem_rdata )
+ );
+endmodule
diff --git a/picosoc/icebreaker_tb.v b/picosoc/icebreaker_tb.v
new file mode 100644
index 0000000..2126ca2
--- /dev/null
+++ b/picosoc/icebreaker_tb.v
@@ -0,0 +1,117 @@
+/*
+ * PicoSoC - A simple example SoC using PicoRV32
+ *
+ * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1 ns / 1 ps
+
+module testbench;
+ reg clk;
+ always #5 clk = (clk === 1'b0);
+
+ localparam ser_half_period = 53;
+ event ser_sample;
+
+ initial begin
+ $dumpfile("testbench.vcd");
+ $dumpvars(0, testbench);
+
+ repeat (6) begin
+ repeat (50000) @(posedge clk);
+ $display("+50000 cycles");
+ end
+ $finish;
+ end
+
+ integer cycle_cnt = 0;
+
+ always @(posedge clk) begin
+ cycle_cnt <= cycle_cnt + 1;
+ end
+
+ wire led1, led2, led3, led4, led5;
+ wire ledr_n, ledg_n;
+
+ wire [6:0] leds = {!ledg_n, !ledr_n, led5, led4, led3, led2, led1};
+
+ wire ser_rx;
+ wire ser_tx;
+
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire flash_io2;
+ wire flash_io3;
+
+ always @(leds) begin
+ #1 $display("%b", leds);
+ end
+
+ icebreaker uut (
+ .clk (clk ),
+ .led1 (led1 ),
+ .led2 (led2 ),
+ .led3 (led3 ),
+ .led4 (led4 ),
+ .led5 (led5 ),
+ .ledr_n (ledr_n ),
+ .ledg_n (ledg_n ),
+ .ser_rx (ser_rx ),
+ .ser_tx (ser_tx ),
+ .flash_csb(flash_csb),
+ .flash_clk(flash_clk),
+ .flash_io0(flash_io0),
+ .flash_io1(flash_io1),
+ .flash_io2(flash_io2),
+ .flash_io3(flash_io3)
+ );
+
+ spiflash spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(flash_io2),
+ .io3(flash_io3)
+ );
+
+ reg [7:0] buffer;
+
+ always begin
+ @(negedge ser_tx);
+
+ repeat (ser_half_period) @(posedge clk);
+ -> ser_sample; // start bit
+
+ repeat (8) begin
+ repeat (ser_half_period) @(posedge clk);
+ repeat (ser_half_period) @(posedge clk);
+ buffer = {ser_tx, buffer[7:1]};
+ -> ser_sample; // data bit
+ end
+
+ repeat (ser_half_period) @(posedge clk);
+ repeat (ser_half_period) @(posedge clk);
+ -> ser_sample; // stop bit
+
+ if (buffer < 32 || buffer >= 127)
+ $display("Serial data: %d", buffer);
+ else
+ $display("Serial data: '%c'", buffer);
+ end
+endmodule
diff --git a/picosoc/picosoc.v b/picosoc/picosoc.v
index b38d6f2..353f2ef 100644
--- a/picosoc/picosoc.v
+++ b/picosoc/picosoc.v
@@ -61,7 +61,12 @@ module picosoc (
input flash_io2_di,
input flash_io3_di
);
+ parameter [0:0] BARREL_SHIFTER = 1;
+ parameter [0:0] ENABLE_MULDIV = 1;
+ parameter [0:0] ENABLE_COMPRESSED = 1;
+ parameter [0:0] ENABLE_COUNTERS = 1;
parameter [0:0] ENABLE_IRQ_QREGS = 0;
+
parameter integer MEM_WORDS = 256;
parameter [31:0] STACKADDR = (4*MEM_WORDS); // end of memory
parameter [31:0] PROGADDR_RESET = 32'h 0010_0000; // 1 MB into flash
@@ -120,10 +125,11 @@ module picosoc (
.STACKADDR(STACKADDR),
.PROGADDR_RESET(PROGADDR_RESET),
.PROGADDR_IRQ(PROGADDR_IRQ),
- .BARREL_SHIFTER(1),
- .COMPRESSED_ISA(1),
- .ENABLE_MUL(1),
- .ENABLE_DIV(1),
+ .BARREL_SHIFTER(BARREL_SHIFTER),
+ .COMPRESSED_ISA(ENABLE_COMPRESSED),
+ .ENABLE_COUNTERS(ENABLE_COUNTERS),
+ .ENABLE_MUL(ENABLE_MULDIV),
+ .ENABLE_DIV(ENABLE_MULDIV),
.ENABLE_IRQ(1),
.ENABLE_IRQ_QREGS(ENABLE_IRQ_QREGS)
) cpu (