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.hex
|
||||
/firmware.bin
|
||||
/design.asc
|
||||
/design.bin
|
||||
/design.blif
|
||||
/design.log
|
||||
/design.rpt
|
||||
/hx8kdemo.asc
|
||||
/hx8kdemo.bin
|
||||
/hx8kdemo.blif
|
||||
/hx8kdemo.log
|
||||
/hx8kdemo.rpt
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
# ---- Generic Testbenches ----
|
||||
|
||||
testbench: testbench.vvp firmware.hex
|
||||
vvp -N $<
|
||||
|
||||
|
@ -11,10 +13,24 @@ spiflash_tb: spiflash_tb.vvp firmware.hex
|
|||
spiflash_tb.vvp: spiflash.v spiflash_tb.v
|
||||
iverilog -s testbench -o $@ $^
|
||||
|
||||
prog: design.bin firmware.bin
|
||||
iceprog design.bin
|
||||
# ---- iCE40 HX8K Breakout Board ----
|
||||
|
||||
hx8kprog: hx8kdemo.bin firmware.bin
|
||||
iceprog hx8kdemo.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
|
||||
riscv32-unknown-elf-gcc -c -o firmware.elf firmware.s
|
||||
|
||||
|
@ -27,20 +43,12 @@ firmware.hex: firmware_vma.elf
|
|||
firmware.bin: firmware.elf
|
||||
riscv32-unknown-elf-objcopy -O binary firmware.elf firmware.bin
|
||||
|
||||
design.blif: spimemio.v picosoc.v ../picorv32.v
|
||||
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 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
|
||||
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
|
||||
vector is set to 0x80100000, i.e. at the 1MB offset inside the flash memory.
|
||||
The flash is mapped to the memory region starting at 0x01000000. The reset
|
||||
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
|
||||
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 prog` to build the configuration bit-stream and firmware images
|
||||
and upload them to a connected iCE40-HX8K Breakout Board.
|
||||
|
||||
| File | Description |
|
||||
| --------------------------- | --------------------------------------------------------------- |
|
||||
| [picosoc.v](picosoc.v) | Top-level Verilog module for the design |
|
||||
| [spimemio.v](spimemio.v) | Memory controller that interfaces to external SPI flash |
|
||||
| [spiflash.v](spiflash.v) | Simulation model of an SPI flash (used by testbench.v) |
|
||||
| [testbench.v](testbench.v) | Simple test bench for the design (requires firmware.hex). |
|
||||
| [firmware.s](firmware.s) | Assembler source for firmware.hex/firmware.bin. |
|
||||
| [pinout.pcf](pinout.pcf) | Pin constraints for implementation on iCE40-HX8K Breakout Board |
|
||||
| File | Description |
|
||||
| ----------------------------- | --------------------------------------------------------------- |
|
||||
| [picosoc.v](picosoc.v) | Top-level PicoSoC Verilog module |
|
||||
| [picosoc.v](picosoc.v) | Top-level PicoSoC Verilog module |
|
||||
| [spimemio.v](spimemio.v) | Memory controller that interfaces to external SPI flash |
|
||||
| [spiflash.v](spiflash.v) | Simulation model of an SPI flash (used by testbench.v) |
|
||||
| [testbench.v](testbench.v) | Simple test bench for the design (requires firmware.hex). |
|
||||
| [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)
|
||||
|
||||
# setup gpio address in x5
|
||||
li x5,0xc0000000
|
||||
li x5,0x02000000
|
||||
sw x0,0(x5)
|
||||
|
||||
# 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 (
|
||||
input clk,
|
||||
output trap,
|
||||
input resetn,
|
||||
|
||||
input [31:0] gpio_i,
|
||||
output reg [31:0] gpio_o,
|
||||
output iomem_valid,
|
||||
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_clk,
|
||||
output flash_io0,
|
||||
input flash_io1,
|
||||
input flash_io2,
|
||||
input flash_io3
|
||||
|
||||
output flash_io0_oe,
|
||||
output flash_io1_oe,
|
||||
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 [31:0] STACKADDR = (4*MEM_WORDS); // end of memory
|
||||
parameter [31:0] PROGADDR_RESET = 32'h 8010_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
|
||||
parameter [31:0] PROGADDR_RESET = 32'h 0110_0000; // 1 MB into flash
|
||||
|
||||
wire mem_valid;
|
||||
wire mem_instr;
|
||||
reg mem_ready;
|
||||
wire mem_ready;
|
||||
wire [31:0] mem_addr;
|
||||
wire [31:0] mem_wdata;
|
||||
wire [3:0] mem_wstrb;
|
||||
reg [31:0] mem_rdata;
|
||||
wire [31:0] mem_rdata;
|
||||
|
||||
wire spimem_ready;
|
||||
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 #(
|
||||
.STACKADDR(STACKADDR),
|
||||
.PROGADDR_RESET(PROGADDR_RESET)
|
||||
) cpu (
|
||||
.clk (clk ),
|
||||
.resetn (resetn ),
|
||||
.trap (trap ),
|
||||
.mem_valid (mem_valid ),
|
||||
.mem_instr (mem_instr ),
|
||||
.mem_ready (mem_ready || spimem_ready),
|
||||
.mem_ready (mem_ready ),
|
||||
.mem_addr (mem_addr ),
|
||||
.mem_wdata (mem_wdata ),
|
||||
.mem_wstrb (mem_wstrb ),
|
||||
.mem_rdata (spimem_ready ? spimem_rdata : mem_rdata )
|
||||
.mem_rdata (mem_rdata )
|
||||
);
|
||||
|
||||
spimemio spimemio (
|
||||
.clk(clk),
|
||||
.resetn(resetn),
|
||||
.valid (mem_valid && mem_addr[31:30] == 2'b10),
|
||||
.valid (mem_valid && mem_addr[31:24] == 8'h 01),
|
||||
.ready (spimem_ready),
|
||||
.addr (mem_addr[23:0]),
|
||||
.rdata (spimem_rdata),
|
||||
|
||||
.flash_csb (flash_csb),
|
||||
.flash_clk (flash_clk),
|
||||
.flash_io0 (flash_io0),
|
||||
.flash_io1 (flash_io1),
|
||||
.flash_io2 (flash_io2),
|
||||
.flash_io3 (flash_io3)
|
||||
|
||||
.flash_io0 (flash_io0_do),
|
||||
.flash_io1 (flash_io1_di),
|
||||
.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];
|
||||
|
||||
always @(posedge clk) begin
|
||||
mem_ready <= 0;
|
||||
if (mem_valid && !mem_ready) begin
|
||||
if (mem_addr < 4*MEM_WORDS) begin
|
||||
mem_ready <= 1;
|
||||
mem_rdata <= memory[mem_addr >> 2];
|
||||
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[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];
|
||||
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
|
||||
ram_ready <= 0;
|
||||
if (mem_valid && !mem_ready && mem_addr[31:24] == 8'h 00) begin
|
||||
ram_ready <= 1;
|
||||
ram_rdata <= memory[mem_addr >> 2];
|
||||
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[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];
|
||||
end
|
||||
end
|
||||
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;
|
||||
reg clk = 1;
|
||||
always #5 clk = ~clk;
|
||||
reg clk;
|
||||
always #5 clk = (clk === 1'b0);
|
||||
|
||||
reg resetn = 0;
|
||||
|
||||
initial begin
|
||||
$dumpfile("testbench.vcd");
|
||||
$dumpvars(0, testbench);
|
||||
|
||||
repeat (100) @(posedge clk);
|
||||
resetn <= 1;
|
||||
|
||||
repeat (100000) @(posedge clk);
|
||||
|
||||
$display("");
|
||||
$display("[TIMEOUT]");
|
||||
$stop;
|
||||
|
@ -35,32 +42,92 @@ module testbench;
|
|||
|
||||
wire flash_csb;
|
||||
wire flash_clk;
|
||||
|
||||
wire flash_io0;
|
||||
wire flash_io1;
|
||||
wire flash_io2;
|
||||
wire flash_io3;
|
||||
|
||||
always @(gpio_o) begin
|
||||
$write("<GPIO:%02x>", gpio_o[7:0]);
|
||||
if (gpio_o == 63) begin
|
||||
wire flash_io0_oe;
|
||||
wire flash_io1_oe;
|
||||
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]");
|
||||
$finish;
|
||||
end
|
||||
if (gpio_o % 8 == 7) begin
|
||||
if (gpio % 8 == 7) begin
|
||||
$display("");
|
||||
end
|
||||
end
|
||||
|
||||
picosoc uut (
|
||||
.clk (clk ),
|
||||
.gpio_i (gpio_i ),
|
||||
.gpio_o (gpio_o ),
|
||||
.flash_csb(flash_csb),
|
||||
.flash_clk(flash_clk),
|
||||
.flash_io0(flash_io0),
|
||||
.flash_io1(flash_io1),
|
||||
.flash_io2(flash_io2),
|
||||
.flash_io3(flash_io3)
|
||||
.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 )
|
||||
);
|
||||
|
||||
spiflash spiflash (
|
||||
|
|
Loading…
Reference in New Issue