Add PicoSoC IceBreaker demo

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-08-18 20:17:21 +02:00
parent b634224ccb
commit 1afe3af452
7 changed files with 341 additions and 8 deletions

8
picosoc/.gitignore vendored
View File

@ -11,5 +11,13 @@
/hx8kdemo_syn.v /hx8kdemo_syn.v
/hx8kdemo_syn_tb.vvp /hx8kdemo_syn_tb.vvp
/hx8kdemo_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 /testbench.vcd
/cmos.log /cmos.log

View File

@ -33,10 +33,44 @@ hx8kprog: hx8kdemo.bin firmware.bin
hx8kprog_fw: firmware.bin hx8kprog_fw: firmware.bin
iceprog -o 1M 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 ---- # ---- Example Firmware ----
firmware.elf: sections.lds start.s firmware.c 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 firmware.hex: firmware.elf
riscv32-unknown-elf-objcopy -O verilog firmware.elf firmware.hex 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 firmware.elf firmware.hex firmware.bin cmos.log
rm -f hx8kdemo.blif hx8kdemo.log hx8kdemo.asc hx8kdemo.rpt hx8kdemo.bin 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 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

View File

@ -32,7 +32,7 @@ void set_flash_qspi_flag()
{ {
uint8_t buffer[8]; uint8_t buffer[8];
#if 0 #if 1
uint32_t addr_cr1v = 0x800002; uint32_t addr_cr1v = 0x800002;
// Read Any Register (RDAR 65h) // Read Any Register (RDAR 65h)

25
picosoc/icebreaker.pcf Normal file
View File

@ -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
picosoc/icebreaker.v Normal file
View File

@ -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
picosoc/icebreaker_tb.v Normal file
View File

@ -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

View File

@ -61,7 +61,12 @@ module picosoc (
input flash_io2_di, input flash_io2_di,
input flash_io3_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 [0:0] ENABLE_IRQ_QREGS = 0;
parameter integer MEM_WORDS = 256; parameter integer MEM_WORDS = 256;
parameter [31:0] STACKADDR = (4*MEM_WORDS); // end of memory parameter [31:0] STACKADDR = (4*MEM_WORDS); // end of memory
parameter [31:0] PROGADDR_RESET = 32'h 0010_0000; // 1 MB into flash parameter [31:0] PROGADDR_RESET = 32'h 0010_0000; // 1 MB into flash
@ -120,10 +125,11 @@ module picosoc (
.STACKADDR(STACKADDR), .STACKADDR(STACKADDR),
.PROGADDR_RESET(PROGADDR_RESET), .PROGADDR_RESET(PROGADDR_RESET),
.PROGADDR_IRQ(PROGADDR_IRQ), .PROGADDR_IRQ(PROGADDR_IRQ),
.BARREL_SHIFTER(1), .BARREL_SHIFTER(BARREL_SHIFTER),
.COMPRESSED_ISA(1), .COMPRESSED_ISA(ENABLE_COMPRESSED),
.ENABLE_MUL(1), .ENABLE_COUNTERS(ENABLE_COUNTERS),
.ENABLE_DIV(1), .ENABLE_MUL(ENABLE_MULDIV),
.ENABLE_DIV(ENABLE_MULDIV),
.ENABLE_IRQ(1), .ENABLE_IRQ(1),
.ENABLE_IRQ_QREGS(ENABLE_IRQ_QREGS) .ENABLE_IRQ_QREGS(ENABLE_IRQ_QREGS)
) cpu ( ) cpu (