mirror of https://github.com/YosysHQ/picorv32.git
Refactor picosoc code
This commit is contained in:
parent
caef4e3753
commit
db2222ec02
|
@ -6,8 +6,8 @@
|
||||||
/firmware_vma.elf
|
/firmware_vma.elf
|
||||||
/firmware.hex
|
/firmware.hex
|
||||||
/firmware.bin
|
/firmware.bin
|
||||||
/design.asc
|
/hx8kdemo.asc
|
||||||
/design.bin
|
/hx8kdemo.bin
|
||||||
/design.blif
|
/hx8kdemo.blif
|
||||||
/design.log
|
/hx8kdemo.log
|
||||||
/design.rpt
|
/hx8kdemo.rpt
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
|
# ---- Generic Testbenches ----
|
||||||
|
|
||||||
testbench: testbench.vvp firmware.hex
|
testbench: testbench.vvp firmware.hex
|
||||||
vvp -N $<
|
vvp -N $<
|
||||||
|
|
||||||
|
@ -11,10 +13,24 @@ spiflash_tb: spiflash_tb.vvp firmware.hex
|
||||||
spiflash_tb.vvp: spiflash.v spiflash_tb.v
|
spiflash_tb.vvp: spiflash.v spiflash_tb.v
|
||||||
iverilog -s testbench -o $@ $^
|
iverilog -s testbench -o $@ $^
|
||||||
|
|
||||||
prog: design.bin firmware.bin
|
# ---- iCE40 HX8K Breakout Board ----
|
||||||
iceprog design.bin
|
|
||||||
|
hx8kprog: hx8kdemo.bin firmware.bin
|
||||||
|
iceprog hx8kdemo.bin
|
||||||
iceprog -o 1M firmware.bin
|
iceprog -o 1M firmware.bin
|
||||||
|
|
||||||
|
hx8kdemo.blif: hx8kdemo.v spimemio.v picosoc.v ../picorv32.v
|
||||||
|
yosys -ql hx8kdemo.log -p 'synth_ice40 -top hx8kdemo -blif hx8kdemo.blif' $^
|
||||||
|
|
||||||
|
hx8kdemo.asc: hx8kdemo.pcf hx8kdemo.blif
|
||||||
|
arachne-pnr -d 8k -o hx8kdemo.asc -p hx8kdemo.pcf hx8kdemo.blif
|
||||||
|
|
||||||
|
hx8kdemo.bin: hx8kdemo.asc
|
||||||
|
icetime -d hx8k -c 12 -mtr hx8kdemo.rpt hx8kdemo.asc
|
||||||
|
icepack hx8kdemo.asc hx8kdemo.bin
|
||||||
|
|
||||||
|
# ---- Example Firmware ----
|
||||||
|
|
||||||
firmware.elf: firmware.s
|
firmware.elf: firmware.s
|
||||||
riscv32-unknown-elf-gcc -c -o firmware.elf firmware.s
|
riscv32-unknown-elf-gcc -c -o firmware.elf firmware.s
|
||||||
|
|
||||||
|
@ -27,20 +43,12 @@ firmware.hex: firmware_vma.elf
|
||||||
firmware.bin: firmware.elf
|
firmware.bin: firmware.elf
|
||||||
riscv32-unknown-elf-objcopy -O binary firmware.elf firmware.bin
|
riscv32-unknown-elf-objcopy -O binary firmware.elf firmware.bin
|
||||||
|
|
||||||
design.blif: spimemio.v picosoc.v ../picorv32.v
|
# ---- Clean ----
|
||||||
yosys -ql design.log -p 'synth_ice40 -top picosoc -blif design.blif' $^
|
|
||||||
|
|
||||||
design.asc: pinout.pcf design.blif
|
|
||||||
arachne-pnr -d 8k -o design.asc -p pinout.pcf design.blif
|
|
||||||
|
|
||||||
design.bin: design.asc
|
|
||||||
icetime -d hx8k -c 12 -mtr design.rpt design.asc
|
|
||||||
icepack design.asc design.bin
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f testbench.vvp testbench.vcd spiflash_tb.vvp spiflash_tb.vcd
|
rm -f testbench.vvp testbench.vcd spiflash_tb.vvp spiflash_tb.vcd
|
||||||
rm -f firmware.elf firmware_vma.elf firmware.hex firmware.bin
|
rm -f firmware.elf firmware_vma.elf firmware.hex firmware.bin
|
||||||
rm -f design.blif design.log design.asc design.rpt design.bin
|
rm -f hx8kdemo.blif hx8kdemo.log hx8kdemo.asc hx8kdemo.rpt hx8kdemo.bin
|
||||||
|
|
||||||
.PHONY: testbench spiflash_tb prog clean
|
.PHONY: testbench spiflash_tb hx8kprog clean
|
||||||
|
|
||||||
|
|
|
@ -5,23 +5,25 @@ PicoSoC - A simple example SoC using PicoRV32
|
||||||
This is a simple PicoRV32 example design that can run code directly from an SPI
|
This is a simple PicoRV32 example design that can run code directly from an SPI
|
||||||
flash chip. This example design uses the Lattice iCE40-HX8K Breakout Board.
|
flash chip. This example design uses the Lattice iCE40-HX8K Breakout Board.
|
||||||
|
|
||||||
The flash is mapped to the memory region starting at 0x80000000. The reset
|
The flash is mapped to the memory region starting at 0x01000000. The reset
|
||||||
vector is set to 0x80100000, i.e. at the 1MB offset inside the flash memory.
|
vector is set to 0x01100000, i.e. at the 1MB offset inside the flash memory.
|
||||||
|
|
||||||
A small scratchpad memory (default 256 words, i.e. 1 kB) is mapped to address
|
A small scratchpad memory (default 256 words, i.e. 1 kB) is mapped to address
|
||||||
0x00000000. A simple GPIO controller is mapped to address 0xC0000000.
|
0x00000000.
|
||||||
|
|
||||||
Run `make test` to run the test bench (and create `testbench.vcd`).
|
Run `make test` to run the test bench (and create `testbench.vcd`).
|
||||||
|
|
||||||
Run `make prog` to build the configuration bit-stream and firmware images
|
Run `make prog` to build the configuration bit-stream and firmware images
|
||||||
and upload them to a connected iCE40-HX8K Breakout Board.
|
and upload them to a connected iCE40-HX8K Breakout Board.
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
| --------------------------- | --------------------------------------------------------------- |
|
| ----------------------------- | --------------------------------------------------------------- |
|
||||||
| [picosoc.v](picosoc.v) | Top-level Verilog module for the design |
|
| [picosoc.v](picosoc.v) | Top-level PicoSoC Verilog module |
|
||||||
| [spimemio.v](spimemio.v) | Memory controller that interfaces to external SPI flash |
|
| [picosoc.v](picosoc.v) | Top-level PicoSoC Verilog module |
|
||||||
| [spiflash.v](spiflash.v) | Simulation model of an SPI flash (used by testbench.v) |
|
| [spimemio.v](spimemio.v) | Memory controller that interfaces to external SPI flash |
|
||||||
| [testbench.v](testbench.v) | Simple test bench for the design (requires firmware.hex). |
|
| [spiflash.v](spiflash.v) | Simulation model of an SPI flash (used by testbench.v) |
|
||||||
| [firmware.s](firmware.s) | Assembler source for firmware.hex/firmware.bin. |
|
| [testbench.v](testbench.v) | Simple test bench for the design (requires firmware.hex). |
|
||||||
| [pinout.pcf](pinout.pcf) | Pin constraints for implementation on iCE40-HX8K Breakout Board |
|
| [firmware.s](firmware.s) | Assembler source for firmware.hex/firmware.bin. |
|
||||||
|
| [hx8kdemo.v](hx8kdemo.v) | FPGA-based example implementation on iCE40-HX8K Breakout Board |
|
||||||
|
| [hx8kdemo.pcf](hx8kdemo.pcf) | Pin constraints for implementation on iCE40-HX8K Breakout Board |
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ li x5,0x00008067 # ret
|
||||||
sw x5,80(x0)
|
sw x5,80(x0)
|
||||||
|
|
||||||
# setup gpio address in x5
|
# setup gpio address in x5
|
||||||
li x5,0xc0000000
|
li x5,0x02000000
|
||||||
sw x0,0(x5)
|
sw x0,0(x5)
|
||||||
|
|
||||||
# initial entry point into RAM code
|
# initial entry point into RAM code
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
# Pinout for the iCE40-HX8K Breakout Board
|
||||||
|
|
||||||
|
set_io clk J3
|
||||||
|
|
||||||
|
set_io flash_csb R12
|
||||||
|
set_io flash_clk R11
|
||||||
|
set_io flash_io0 P12
|
||||||
|
set_io flash_io1 P11
|
||||||
|
set_io flash_io2 T9 # center on J3
|
||||||
|
set_io flash_io3 P8 # center on J3
|
||||||
|
|
||||||
|
set_io ser_tx B12
|
||||||
|
set_io ser_rx B10
|
||||||
|
|
||||||
|
set_io leds[0] B5 # LED0
|
||||||
|
set_io leds[1] B4 # LED1
|
||||||
|
set_io leds[2] A2 # LED2
|
||||||
|
set_io leds[3] A1 # LED3
|
||||||
|
set_io leds[4] C5 # LED4
|
||||||
|
set_io leds[5] C4 # LED5
|
||||||
|
set_io leds[6] B3 # LED6
|
||||||
|
set_io leds[7] C3 # LED7
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* 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 hx8kdemo (
|
||||||
|
input clk,
|
||||||
|
|
||||||
|
input ser_tx,
|
||||||
|
input ser_rx,
|
||||||
|
|
||||||
|
output [7:0] leds,
|
||||||
|
|
||||||
|
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 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 >> 12;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
iomem_ready <= 0;
|
||||||
|
if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 02) 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
|
||||||
|
|
||||||
|
picosoc uut (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
|
||||||
|
.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),
|
||||||
|
|
||||||
|
.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
|
|
@ -19,93 +19,111 @@
|
||||||
|
|
||||||
module picosoc (
|
module picosoc (
|
||||||
input clk,
|
input clk,
|
||||||
output trap,
|
input resetn,
|
||||||
|
|
||||||
input [31:0] gpio_i,
|
output iomem_valid,
|
||||||
output reg [31:0] gpio_o,
|
input iomem_ready,
|
||||||
|
output [ 3:0] iomem_wstrb,
|
||||||
|
output [31:0] iomem_addr,
|
||||||
|
output [31:0] iomem_wdata,
|
||||||
|
input [31:0] iomem_rdata,
|
||||||
|
|
||||||
output flash_csb,
|
output flash_csb,
|
||||||
output flash_clk,
|
output flash_clk,
|
||||||
output flash_io0,
|
|
||||||
input flash_io1,
|
output flash_io0_oe,
|
||||||
input flash_io2,
|
output flash_io1_oe,
|
||||||
input flash_io3
|
output flash_io2_oe,
|
||||||
|
output flash_io3_oe,
|
||||||
|
|
||||||
|
output flash_io0_do,
|
||||||
|
output flash_io1_do,
|
||||||
|
output flash_io2_do,
|
||||||
|
output flash_io3_do,
|
||||||
|
|
||||||
|
input flash_io0_di,
|
||||||
|
input flash_io1_di,
|
||||||
|
input flash_io2_di,
|
||||||
|
input flash_io3_di
|
||||||
);
|
);
|
||||||
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 8010_0000; // 1 MB into flash
|
parameter [31:0] PROGADDR_RESET = 32'h 0110_0000; // 1 MB into flash
|
||||||
|
|
||||||
reg [5:0] reset_cnt = 0;
|
|
||||||
wire resetn = &reset_cnt;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
reset_cnt <= reset_cnt + !resetn;
|
|
||||||
end
|
|
||||||
|
|
||||||
wire mem_valid;
|
wire mem_valid;
|
||||||
wire mem_instr;
|
wire mem_instr;
|
||||||
reg mem_ready;
|
wire mem_ready;
|
||||||
wire [31:0] mem_addr;
|
wire [31:0] mem_addr;
|
||||||
wire [31:0] mem_wdata;
|
wire [31:0] mem_wdata;
|
||||||
wire [3:0] mem_wstrb;
|
wire [3:0] mem_wstrb;
|
||||||
reg [31:0] mem_rdata;
|
wire [31:0] mem_rdata;
|
||||||
|
|
||||||
wire spimem_ready;
|
wire spimem_ready;
|
||||||
wire [31:0] spimem_rdata;
|
wire [31:0] spimem_rdata;
|
||||||
|
|
||||||
|
reg ram_ready;
|
||||||
|
reg [31:0] ram_rdata;
|
||||||
|
|
||||||
|
assign iomem_valid = mem_valid && (mem_addr[31:24] > 8'h 01);
|
||||||
|
assign iomem_wstrb = mem_wstrb;
|
||||||
|
assign iomem_addr = mem_addr;
|
||||||
|
assign iomem_wdata = mem_wdata;
|
||||||
|
|
||||||
|
assign mem_ready = (iomem_valid && iomem_ready) || spimem_ready || ram_ready;
|
||||||
|
assign mem_rdata = (iomem_valid && iomem_ready) ? iomem_rdata : spimem_ready ? spimem_rdata : ram_ready ? ram_rdata : 32'h xxxx_xxxx;
|
||||||
|
|
||||||
picorv32 #(
|
picorv32 #(
|
||||||
.STACKADDR(STACKADDR),
|
.STACKADDR(STACKADDR),
|
||||||
.PROGADDR_RESET(PROGADDR_RESET)
|
.PROGADDR_RESET(PROGADDR_RESET)
|
||||||
) cpu (
|
) cpu (
|
||||||
.clk (clk ),
|
.clk (clk ),
|
||||||
.resetn (resetn ),
|
.resetn (resetn ),
|
||||||
.trap (trap ),
|
|
||||||
.mem_valid (mem_valid ),
|
.mem_valid (mem_valid ),
|
||||||
.mem_instr (mem_instr ),
|
.mem_instr (mem_instr ),
|
||||||
.mem_ready (mem_ready || spimem_ready),
|
.mem_ready (mem_ready ),
|
||||||
.mem_addr (mem_addr ),
|
.mem_addr (mem_addr ),
|
||||||
.mem_wdata (mem_wdata ),
|
.mem_wdata (mem_wdata ),
|
||||||
.mem_wstrb (mem_wstrb ),
|
.mem_wstrb (mem_wstrb ),
|
||||||
.mem_rdata (spimem_ready ? spimem_rdata : mem_rdata )
|
.mem_rdata (mem_rdata )
|
||||||
);
|
);
|
||||||
|
|
||||||
spimemio spimemio (
|
spimemio spimemio (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.resetn(resetn),
|
.resetn(resetn),
|
||||||
.valid (mem_valid && mem_addr[31:30] == 2'b10),
|
.valid (mem_valid && mem_addr[31:24] == 8'h 01),
|
||||||
.ready (spimem_ready),
|
.ready (spimem_ready),
|
||||||
.addr (mem_addr[23:0]),
|
.addr (mem_addr[23:0]),
|
||||||
.rdata (spimem_rdata),
|
.rdata (spimem_rdata),
|
||||||
|
|
||||||
.flash_csb (flash_csb),
|
.flash_csb (flash_csb),
|
||||||
.flash_clk (flash_clk),
|
.flash_clk (flash_clk),
|
||||||
.flash_io0 (flash_io0),
|
|
||||||
.flash_io1 (flash_io1),
|
.flash_io0 (flash_io0_do),
|
||||||
.flash_io2 (flash_io2),
|
.flash_io1 (flash_io1_di),
|
||||||
.flash_io3 (flash_io3)
|
.flash_io2 (flash_io2_di),
|
||||||
|
.flash_io3 (flash_io3_di)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assign flash_io0_oe = 1;
|
||||||
|
assign flash_io1_oe = 0;
|
||||||
|
assign flash_io2_oe = 0;
|
||||||
|
assign flash_io3_oe = 0;
|
||||||
|
|
||||||
|
assign flash_io1_do = 0;
|
||||||
|
assign flash_io2_do = 0;
|
||||||
|
assign flash_io3_do = 0;
|
||||||
|
|
||||||
reg [31:0] memory [0:MEM_WORDS-1];
|
reg [31:0] memory [0:MEM_WORDS-1];
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
mem_ready <= 0;
|
ram_ready <= 0;
|
||||||
if (mem_valid && !mem_ready) begin
|
if (mem_valid && !mem_ready && mem_addr[31:24] == 8'h 00) begin
|
||||||
if (mem_addr < 4*MEM_WORDS) begin
|
ram_ready <= 1;
|
||||||
mem_ready <= 1;
|
ram_rdata <= memory[mem_addr >> 2];
|
||||||
mem_rdata <= memory[mem_addr >> 2];
|
if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0];
|
||||||
if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0];
|
if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8];
|
||||||
if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8];
|
if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16];
|
||||||
if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16];
|
if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24];
|
||||||
if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24];
|
|
||||||
end
|
|
||||||
if (mem_addr == 32'h c000_0000) begin
|
|
||||||
mem_ready <= 1;
|
|
||||||
mem_rdata <= gpio_i;
|
|
||||||
if (mem_wstrb[0]) gpio_o[ 7: 0] <= mem_wdata[ 7: 0];
|
|
||||||
if (mem_wstrb[1]) gpio_o[15: 8] <= mem_wdata[15: 8];
|
|
||||||
if (mem_wstrb[2]) gpio_o[23:16] <= mem_wdata[23:16];
|
|
||||||
if (mem_wstrb[3]) gpio_o[31:24] <= mem_wdata[31:24];
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
|
|
||||||
# Pinout for the iCE40-HX8K Breakout Board
|
|
||||||
|
|
||||||
set_io clk J3
|
|
||||||
|
|
||||||
set_io flash_csb R12
|
|
||||||
set_io flash_clk R11
|
|
||||||
set_io flash_io0 P12
|
|
||||||
set_io flash_io1 P11
|
|
||||||
set_io flash_io2 T9 # center on J3
|
|
||||||
set_io flash_io3 P8 # center on J3
|
|
||||||
|
|
||||||
# All the GPIO pins below are connected to pins that are floating
|
|
||||||
# on the iCE40-HX8K Breakout Board, expect the marked LED pins.
|
|
||||||
|
|
||||||
set_io trap C3 # LED7
|
|
||||||
|
|
||||||
set_io gpio_o[0] C14
|
|
||||||
set_io gpio_o[1] D13
|
|
||||||
set_io gpio_o[2] C12
|
|
||||||
set_io gpio_o[3] E11
|
|
||||||
set_io gpio_o[4] C13
|
|
||||||
set_io gpio_o[5] E10
|
|
||||||
set_io gpio_o[6] C11
|
|
||||||
set_io gpio_o[7] D11
|
|
||||||
set_io gpio_o[8] C10
|
|
||||||
set_io gpio_o[9] D10
|
|
||||||
set_io gpio_o[10] L10
|
|
||||||
set_io gpio_o[11] E9
|
|
||||||
set_io gpio_o[12] B5 # LED0
|
|
||||||
set_io gpio_o[13] B4 # LED1
|
|
||||||
set_io gpio_o[14] A2 # LED2
|
|
||||||
set_io gpio_o[15] A1 # LED3
|
|
||||||
set_io gpio_o[16] C5 # LED4
|
|
||||||
set_io gpio_o[17] C4 # LED5
|
|
||||||
set_io gpio_o[18] B3 # LED6
|
|
||||||
set_io gpio_o[19] D9
|
|
||||||
set_io gpio_o[20] F9
|
|
||||||
set_io gpio_o[21] D8
|
|
||||||
set_io gpio_o[22] D7
|
|
||||||
set_io gpio_o[23] D6
|
|
||||||
set_io gpio_o[24] E6
|
|
||||||
set_io gpio_o[25] D5
|
|
||||||
set_io gpio_o[26] D4
|
|
||||||
set_io gpio_o[27] E5
|
|
||||||
set_io gpio_o[28] D3
|
|
||||||
set_io gpio_o[29] M13
|
|
||||||
set_io gpio_o[30] M14
|
|
||||||
set_io gpio_o[31] L12
|
|
||||||
|
|
||||||
set_io gpio_i[0] L13
|
|
||||||
set_io gpio_i[1] L14
|
|
||||||
set_io gpio_i[2] K12
|
|
||||||
set_io gpio_i[3] J10
|
|
||||||
set_io gpio_i[4] J11
|
|
||||||
set_io gpio_i[5] K13
|
|
||||||
set_io gpio_i[6] J12
|
|
||||||
set_io gpio_i[7] J13
|
|
||||||
set_io gpio_i[8] J16
|
|
||||||
set_io gpio_i[9] H13
|
|
||||||
set_io gpio_i[10] H12
|
|
||||||
set_io gpio_i[11] G10
|
|
||||||
set_io gpio_i[12] G11
|
|
||||||
set_io gpio_i[13] G13
|
|
||||||
set_io gpio_i[14] G12
|
|
||||||
set_io gpio_i[15] F12
|
|
||||||
set_io gpio_i[16] F11
|
|
||||||
set_io gpio_i[17] E14
|
|
||||||
set_io gpio_i[18] F13
|
|
||||||
set_io gpio_i[19] E13
|
|
||||||
set_io gpio_i[20] N6
|
|
||||||
set_io gpio_i[21] P4
|
|
||||||
set_io gpio_i[22] N5
|
|
||||||
set_io gpio_i[23] P5
|
|
||||||
set_io gpio_i[24] M7
|
|
||||||
set_io gpio_i[25] N7
|
|
||||||
set_io gpio_i[26] P6
|
|
||||||
set_io gpio_i[27] M8
|
|
||||||
set_io gpio_i[28] L9
|
|
||||||
set_io gpio_i[29] P7
|
|
||||||
set_io gpio_i[30] N9
|
|
||||||
set_io gpio_i[31] M9
|
|
||||||
|
|
|
@ -18,13 +18,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module testbench;
|
module testbench;
|
||||||
reg clk = 1;
|
reg clk;
|
||||||
always #5 clk = ~clk;
|
always #5 clk = (clk === 1'b0);
|
||||||
|
|
||||||
|
reg resetn = 0;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
$dumpfile("testbench.vcd");
|
$dumpfile("testbench.vcd");
|
||||||
$dumpvars(0, testbench);
|
$dumpvars(0, testbench);
|
||||||
|
|
||||||
|
repeat (100) @(posedge clk);
|
||||||
|
resetn <= 1;
|
||||||
|
|
||||||
repeat (100000) @(posedge clk);
|
repeat (100000) @(posedge clk);
|
||||||
|
|
||||||
$display("");
|
$display("");
|
||||||
$display("[TIMEOUT]");
|
$display("[TIMEOUT]");
|
||||||
$stop;
|
$stop;
|
||||||
|
@ -35,32 +42,92 @@ module testbench;
|
||||||
|
|
||||||
wire flash_csb;
|
wire flash_csb;
|
||||||
wire flash_clk;
|
wire flash_clk;
|
||||||
|
|
||||||
wire flash_io0;
|
wire flash_io0;
|
||||||
wire flash_io1;
|
wire flash_io1;
|
||||||
wire flash_io2;
|
wire flash_io2;
|
||||||
wire flash_io3;
|
wire flash_io3;
|
||||||
|
|
||||||
always @(gpio_o) begin
|
wire flash_io0_oe;
|
||||||
$write("<GPIO:%02x>", gpio_o[7:0]);
|
wire flash_io1_oe;
|
||||||
if (gpio_o == 63) begin
|
wire flash_io2_oe;
|
||||||
|
wire flash_io3_oe;
|
||||||
|
|
||||||
|
wire flash_io0_do;
|
||||||
|
wire flash_io1_do;
|
||||||
|
wire flash_io2_do;
|
||||||
|
wire flash_io3_do;
|
||||||
|
|
||||||
|
wire flash_io0_di = flash_io0;
|
||||||
|
wire flash_io1_di = flash_io1;
|
||||||
|
wire flash_io2_di = flash_io2;
|
||||||
|
wire flash_io3_di = flash_io3;
|
||||||
|
|
||||||
|
assign flash_io0 = flash_io0_oe ? flash_io0_do : 1'bz;
|
||||||
|
assign flash_io1 = flash_io1_oe ? flash_io1_do : 1'bz;
|
||||||
|
assign flash_io2 = flash_io2_oe ? flash_io2_do : 1'bz;
|
||||||
|
assign flash_io3 = flash_io3_oe ? flash_io3_do : 1'bz;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
iomem_ready <= 0;
|
||||||
|
if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 02) 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
|
||||||
|
|
||||||
|
always @(gpio) begin
|
||||||
|
$write("<GPIO:%02x>", gpio[7:0]);
|
||||||
|
if (gpio == 63) begin
|
||||||
$display("[OK]");
|
$display("[OK]");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
if (gpio_o % 8 == 7) begin
|
if (gpio % 8 == 7) begin
|
||||||
$display("");
|
$display("");
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
picosoc uut (
|
picosoc uut (
|
||||||
.clk (clk ),
|
.clk (clk ),
|
||||||
.gpio_i (gpio_i ),
|
.resetn (resetn ),
|
||||||
.gpio_o (gpio_o ),
|
|
||||||
.flash_csb(flash_csb),
|
.flash_csb (flash_csb ),
|
||||||
.flash_clk(flash_clk),
|
.flash_clk (flash_clk ),
|
||||||
.flash_io0(flash_io0),
|
|
||||||
.flash_io1(flash_io1),
|
.flash_io0_oe (flash_io0_oe),
|
||||||
.flash_io2(flash_io2),
|
.flash_io1_oe (flash_io1_oe),
|
||||||
.flash_io3(flash_io3)
|
.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),
|
||||||
|
|
||||||
|
.iomem_valid (iomem_valid ),
|
||||||
|
.iomem_ready (iomem_ready ),
|
||||||
|
.iomem_wstrb (iomem_wstrb ),
|
||||||
|
.iomem_addr (iomem_addr ),
|
||||||
|
.iomem_wdata (iomem_wdata ),
|
||||||
|
.iomem_rdata (iomem_rdata )
|
||||||
);
|
);
|
||||||
|
|
||||||
spiflash spiflash (
|
spiflash spiflash (
|
||||||
|
|
Loading…
Reference in New Issue