Skip to content

Commit

Permalink
Add PicoSoC IceBreaker demo
Browse files Browse the repository at this point in the history
Signed-off-by: Clifford Wolf <clifford@clifford.at>
  • Loading branch information
cliffordwolf committed Aug 18, 2018
1 parent b634224 commit 1afe3af
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 8 deletions.
8 changes: 8 additions & 0 deletions picosoc/.gitignore
Expand Up @@ -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
43 changes: 40 additions & 3 deletions picosoc/Makefile
Expand Up @@ -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
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion picosoc/firmware.c
Expand Up @@ -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)
Expand Down
25 changes: 25 additions & 0 deletions 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
140 changes: 140 additions & 0 deletions 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
117 changes: 117 additions & 0 deletions 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
14 changes: 10 additions & 4 deletions picosoc/picosoc.v
Expand Up @@ -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
Expand Down Expand Up @@ -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 (
Expand Down

0 comments on commit 1afe3af

Please sign in to comment.