Add ice40/benchmark/
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
f3dab003e7
commit
5db4a3e8b0
23
ice40/benchmark/Makefile
Normal file
23
ice40/benchmark/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
reports::
|
||||
|
||||
define mkreport
|
||||
reports:: report_a$1.txt report_n$1.txt
|
||||
|
||||
report_a$1.txt: hx8kdemo_a$1.asc
|
||||
icetime -m -r report_a$1.txt -d hx8k hx8kdemo_a$1.asc
|
||||
|
||||
report_n$1.txt: hx8kdemo_n$1.asc
|
||||
icetime -m -r report_n$1.txt -d hx8k hx8kdemo_n$1.asc
|
||||
|
||||
hx8kdemo_a$1.asc: hx8kdemo.blif
|
||||
arachne-pnr -d 8k -p hx8kdemo.pcf -o hx8kdemo_a$1.asc -s $1 hx8kdemo.blif
|
||||
|
||||
hx8kdemo_n$1.asc: hx8kdemo.json
|
||||
nextpnr-ice40 --asc hx8kdemo_n$1.asc --json hx8kdemo.json --pcf hx8kdemo.pcf --hx8k --seed $1
|
||||
endef
|
||||
|
||||
$(foreach i,1 2 3 4 5 6 7 8,$(eval $(call mkreport,$(i))))
|
||||
|
||||
hx8kdemo.blif: hx8kdemo.json
|
||||
hx8kdemo.json: hx8kdemo.v spimemio.v simpleuart.v picosoc.v picorv32.v
|
||||
yosys -ql hx8kdemo.log -p 'synth_ice40 -top hx8kdemo -blif hx8kdemo.blif -json hx8kdemo.json' $^
|
40
ice40/benchmark/hx8kdemo.pcf
Normal file
40
ice40/benchmark/hx8kdemo.pcf
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
# 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
|
||||
|
||||
# for QSPI mode the flash chip on the iCE40-HX8K Breakout Board
|
||||
# must be replaced with one that supports QSPI and the IO2 and IO3
|
||||
# pins must be soldered to T9 and P8 (center on J3)
|
||||
set_io flash_io2 T9
|
||||
set_io flash_io3 P8
|
||||
|
||||
set_io ser_tx B12
|
||||
set_io ser_rx B10
|
||||
|
||||
# left on J3
|
||||
set_io debug_ser_tx T1
|
||||
set_io debug_ser_rx R3
|
||||
|
||||
# right on J3
|
||||
set_io debug_flash_csb T15
|
||||
set_io debug_flash_clk R16
|
||||
set_io debug_flash_io0 N12
|
||||
set_io debug_flash_io1 P13
|
||||
set_io debug_flash_io2 T13
|
||||
set_io debug_flash_io3 T14
|
||||
|
||||
set_io leds[7] B5 # D9
|
||||
set_io leds[6] B4 # D8
|
||||
set_io leds[5] A2 # D7
|
||||
set_io leds[4] A1 # D6
|
||||
set_io leds[3] C5 # D5
|
||||
set_io leds[2] C4 # D4
|
||||
set_io leds[1] B3 # D3
|
||||
set_io leds[0] C3 # D2
|
||||
|
139
ice40/benchmark/hx8kdemo.v
Normal file
139
ice40/benchmark/hx8kdemo.v
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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,
|
||||
|
||||
output 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,
|
||||
|
||||
output debug_ser_tx,
|
||||
output debug_ser_rx,
|
||||
|
||||
output debug_flash_csb,
|
||||
output debug_flash_clk,
|
||||
output debug_flash_io0,
|
||||
output debug_flash_io1,
|
||||
output debug_flash_io2,
|
||||
output debug_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;
|
||||
|
||||
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 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 )
|
||||
);
|
||||
|
||||
assign debug_ser_tx = ser_tx;
|
||||
assign debug_ser_rx = ser_rx;
|
||||
|
||||
assign debug_flash_csb = flash_csb;
|
||||
assign debug_flash_clk = flash_clk;
|
||||
assign debug_flash_io0 = flash_io0_di;
|
||||
assign debug_flash_io1 = flash_io1_di;
|
||||
assign debug_flash_io2 = flash_io2_di;
|
||||
assign debug_flash_io3 = flash_io3_di;
|
||||
endmodule
|
2977
ice40/benchmark/picorv32.v
Normal file
2977
ice40/benchmark/picorv32.v
Normal file
File diff suppressed because it is too large
Load Diff
241
ice40/benchmark/picosoc.v
Normal file
241
ice40/benchmark/picosoc.v
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
`ifndef PICORV32_REGS
|
||||
`ifdef PICORV32_V
|
||||
`error "picosoc.v must be read before picorv32.v!"
|
||||
`endif
|
||||
|
||||
`define PICORV32_REGS picosoc_regs
|
||||
`endif
|
||||
|
||||
module picosoc (
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
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,
|
||||
|
||||
input irq_5,
|
||||
input irq_6,
|
||||
input irq_7,
|
||||
|
||||
output ser_tx,
|
||||
input ser_rx,
|
||||
|
||||
output flash_csb,
|
||||
output flash_clk,
|
||||
|
||||
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 0010_0000; // 1 MB into flash
|
||||
|
||||
reg [31:0] irq;
|
||||
wire irq_stall = 0;
|
||||
wire irq_uart = 0;
|
||||
|
||||
always @* begin
|
||||
irq = 0;
|
||||
irq[3] = irq_stall;
|
||||
irq[4] = irq_uart;
|
||||
irq[5] = irq_5;
|
||||
irq[6] = irq_6;
|
||||
irq[7] = irq_7;
|
||||
end
|
||||
|
||||
wire mem_valid;
|
||||
wire mem_instr;
|
||||
wire mem_ready;
|
||||
wire [31:0] mem_addr;
|
||||
wire [31:0] mem_wdata;
|
||||
wire [3:0] mem_wstrb;
|
||||
wire [31:0] mem_rdata;
|
||||
|
||||
wire spimem_ready;
|
||||
wire [31:0] spimem_rdata;
|
||||
|
||||
reg ram_ready;
|
||||
wire [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;
|
||||
|
||||
wire spimemio_cfgreg_sel = mem_valid && (mem_addr == 32'h 0200_0000);
|
||||
wire [31:0] spimemio_cfgreg_do;
|
||||
|
||||
wire simpleuart_reg_div_sel = mem_valid && (mem_addr == 32'h 0200_0004);
|
||||
wire [31:0] simpleuart_reg_div_do;
|
||||
|
||||
wire simpleuart_reg_dat_sel = mem_valid && (mem_addr == 32'h 0200_0008);
|
||||
wire [31:0] simpleuart_reg_dat_do;
|
||||
wire simpleuart_reg_dat_wait;
|
||||
|
||||
assign mem_ready = (iomem_valid && iomem_ready) || spimem_ready || ram_ready || spimemio_cfgreg_sel ||
|
||||
simpleuart_reg_div_sel || (simpleuart_reg_dat_sel && !simpleuart_reg_dat_wait);
|
||||
|
||||
assign mem_rdata = (iomem_valid && iomem_ready) ? iomem_rdata : spimem_ready ? spimem_rdata : ram_ready ? ram_rdata :
|
||||
spimemio_cfgreg_sel ? spimemio_cfgreg_do : simpleuart_reg_div_sel ? simpleuart_reg_div_do :
|
||||
simpleuart_reg_dat_sel ? simpleuart_reg_dat_do : 32'h 0000_0000;
|
||||
|
||||
picorv32 #(
|
||||
.STACKADDR(STACKADDR),
|
||||
.PROGADDR_RESET(PROGADDR_RESET),
|
||||
.PROGADDR_IRQ(32'h 0000_0000),
|
||||
.BARREL_SHIFTER(1),
|
||||
.COMPRESSED_ISA(1),
|
||||
.ENABLE_MUL(1),
|
||||
.ENABLE_DIV(1),
|
||||
.ENABLE_IRQ(1),
|
||||
.ENABLE_IRQ_QREGS(0)
|
||||
) cpu (
|
||||
.clk (clk ),
|
||||
.resetn (resetn ),
|
||||
.mem_valid (mem_valid ),
|
||||
.mem_instr (mem_instr ),
|
||||
.mem_ready (mem_ready ),
|
||||
.mem_addr (mem_addr ),
|
||||
.mem_wdata (mem_wdata ),
|
||||
.mem_wstrb (mem_wstrb ),
|
||||
.mem_rdata (mem_rdata ),
|
||||
.irq (irq )
|
||||
);
|
||||
|
||||
spimemio spimemio (
|
||||
.clk (clk),
|
||||
.resetn (resetn),
|
||||
.valid (mem_valid && mem_addr >= 4*MEM_WORDS && mem_addr < 32'h 0200_0000),
|
||||
.ready (spimem_ready),
|
||||
.addr (mem_addr[23:0]),
|
||||
.rdata (spimem_rdata),
|
||||
|
||||
.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),
|
||||
|
||||
.cfgreg_we(spimemio_cfgreg_sel ? mem_wstrb : 4'b 0000),
|
||||
.cfgreg_di(mem_wdata),
|
||||
.cfgreg_do(spimemio_cfgreg_do)
|
||||
);
|
||||
|
||||
simpleuart simpleuart (
|
||||
.clk (clk ),
|
||||
.resetn (resetn ),
|
||||
|
||||
.ser_tx (ser_tx ),
|
||||
.ser_rx (ser_rx ),
|
||||
|
||||
.reg_div_we (simpleuart_reg_div_sel ? mem_wstrb : 4'b 0000),
|
||||
.reg_div_di (mem_wdata),
|
||||
.reg_div_do (simpleuart_reg_div_do),
|
||||
|
||||
.reg_dat_we (simpleuart_reg_dat_sel ? mem_wstrb[0] : 1'b 0),
|
||||
.reg_dat_re (simpleuart_reg_dat_sel && !mem_wstrb),
|
||||
.reg_dat_di (mem_wdata),
|
||||
.reg_dat_do (simpleuart_reg_dat_do),
|
||||
.reg_dat_wait(simpleuart_reg_dat_wait)
|
||||
);
|
||||
|
||||
always @(posedge clk)
|
||||
ram_ready <= mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS;
|
||||
|
||||
picosoc_mem #(.WORDS(MEM_WORDS)) memory (
|
||||
.clk(clk),
|
||||
.wen((mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS) ? mem_wstrb : 4'b0),
|
||||
.addr(mem_addr[23:2]),
|
||||
.wdata(mem_wdata),
|
||||
.rdata(ram_rdata)
|
||||
);
|
||||
endmodule
|
||||
|
||||
// Implementation note:
|
||||
// Replace the following two modules with wrappers for your SRAM cells.
|
||||
|
||||
module picosoc_regs (
|
||||
input clk, wen,
|
||||
input [5:0] waddr,
|
||||
input [5:0] raddr1,
|
||||
input [5:0] raddr2,
|
||||
input [31:0] wdata,
|
||||
output [31:0] rdata1,
|
||||
output [31:0] rdata2
|
||||
);
|
||||
reg [31:0] regs [0:31];
|
||||
|
||||
always @(posedge clk)
|
||||
if (wen) regs[waddr[4:0]] <= wdata;
|
||||
|
||||
assign rdata1 = regs[raddr1[4:0]];
|
||||
assign rdata2 = regs[raddr2[4:0]];
|
||||
endmodule
|
||||
|
||||
module picosoc_mem #(
|
||||
parameter integer WORDS = 256
|
||||
) (
|
||||
input clk,
|
||||
input [3:0] wen,
|
||||
input [21:0] addr,
|
||||
input [31:0] wdata,
|
||||
output reg [31:0] rdata
|
||||
);
|
||||
reg [31:0] mem [0:WORDS-1];
|
||||
|
||||
always @(posedge clk) begin
|
||||
rdata <= mem[addr];
|
||||
if (wen[0]) mem[addr][ 7: 0] <= wdata[ 7: 0];
|
||||
if (wen[1]) mem[addr][15: 8] <= wdata[15: 8];
|
||||
if (wen[2]) mem[addr][23:16] <= wdata[23:16];
|
||||
if (wen[3]) mem[addr][31:24] <= wdata[31:24];
|
||||
end
|
||||
endmodule
|
||||
|
137
ice40/benchmark/simpleuart.v
Normal file
137
ice40/benchmark/simpleuart.v
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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 simpleuart (
|
||||
input clk,
|
||||
input resetn,
|
||||
|
||||
output ser_tx,
|
||||
input ser_rx,
|
||||
|
||||
input [3:0] reg_div_we,
|
||||
input [31:0] reg_div_di,
|
||||
output [31:0] reg_div_do,
|
||||
|
||||
input reg_dat_we,
|
||||
input reg_dat_re,
|
||||
input [31:0] reg_dat_di,
|
||||
output [31:0] reg_dat_do,
|
||||
output reg_dat_wait
|
||||
);
|
||||
reg [31:0] cfg_divider;
|
||||
|
||||
reg [3:0] recv_state;
|
||||
reg [31:0] recv_divcnt;
|
||||
reg [7:0] recv_pattern;
|
||||
reg [7:0] recv_buf_data;
|
||||
reg recv_buf_valid;
|
||||
|
||||
reg [9:0] send_pattern;
|
||||
reg [3:0] send_bitcnt;
|
||||
reg [31:0] send_divcnt;
|
||||
reg send_dummy;
|
||||
|
||||
assign reg_div_do = cfg_divider;
|
||||
|
||||
assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
|
||||
assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
cfg_divider <= 1;
|
||||
end else begin
|
||||
if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0];
|
||||
if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8];
|
||||
if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16];
|
||||
if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
recv_state <= 0;
|
||||
recv_divcnt <= 0;
|
||||
recv_pattern <= 0;
|
||||
recv_buf_data <= 0;
|
||||
recv_buf_valid <= 0;
|
||||
end else begin
|
||||
recv_divcnt <= recv_divcnt + 1;
|
||||
if (reg_dat_re)
|
||||
recv_buf_valid <= 0;
|
||||
case (recv_state)
|
||||
0: begin
|
||||
if (!ser_rx)
|
||||
recv_state <= 1;
|
||||
recv_divcnt <= 0;
|
||||
end
|
||||
1: begin
|
||||
if (2*recv_divcnt > cfg_divider) begin
|
||||
recv_state <= 2;
|
||||
recv_divcnt <= 0;
|
||||
end
|
||||
end
|
||||
10: begin
|
||||
if (recv_divcnt > cfg_divider) begin
|
||||
recv_buf_data <= recv_pattern;
|
||||
recv_buf_valid <= 1;
|
||||
recv_state <= 0;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
if (recv_divcnt > cfg_divider) begin
|
||||
recv_pattern <= {ser_rx, recv_pattern[7:1]};
|
||||
recv_state <= recv_state + 1;
|
||||
recv_divcnt <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign ser_tx = send_pattern[0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reg_div_we)
|
||||
send_dummy <= 1;
|
||||
send_divcnt <= send_divcnt + 1;
|
||||
if (!resetn) begin
|
||||
send_pattern <= ~0;
|
||||
send_bitcnt <= 0;
|
||||
send_divcnt <= 0;
|
||||
send_dummy <= 1;
|
||||
end else begin
|
||||
if (send_dummy && !send_bitcnt) begin
|
||||
send_pattern <= ~0;
|
||||
send_bitcnt <= 15;
|
||||
send_divcnt <= 0;
|
||||
send_dummy <= 0;
|
||||
end else
|
||||
if (reg_dat_we && !send_bitcnt) begin
|
||||
send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0};
|
||||
send_bitcnt <= 10;
|
||||
send_divcnt <= 0;
|
||||
end else
|
||||
if (send_divcnt > cfg_divider && send_bitcnt) begin
|
||||
send_pattern <= {1'b1, send_pattern[9:1]};
|
||||
send_bitcnt <= send_bitcnt - 1;
|
||||
send_divcnt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
579
ice40/benchmark/spimemio.v
Normal file
579
ice40/benchmark/spimemio.v
Normal file
@ -0,0 +1,579 @@
|
||||
/*
|
||||
* 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 spimemio (
|
||||
input clk, resetn,
|
||||
|
||||
input valid,
|
||||
output ready,
|
||||
input [23:0] addr,
|
||||
output reg [31:0] rdata,
|
||||
|
||||
output flash_csb,
|
||||
output flash_clk,
|
||||
|
||||
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,
|
||||
|
||||
input [3:0] cfgreg_we,
|
||||
input [31:0] cfgreg_di,
|
||||
output [31:0] cfgreg_do
|
||||
);
|
||||
reg xfer_resetn;
|
||||
reg din_valid;
|
||||
wire din_ready;
|
||||
reg [7:0] din_data;
|
||||
reg [3:0] din_tag;
|
||||
reg din_cont;
|
||||
reg din_qspi;
|
||||
reg din_ddr;
|
||||
reg din_rd;
|
||||
|
||||
wire dout_valid;
|
||||
wire [7:0] dout_data;
|
||||
wire [3:0] dout_tag;
|
||||
|
||||
reg [23:0] buffer;
|
||||
|
||||
reg [23:0] rd_addr;
|
||||
reg rd_valid;
|
||||
reg rd_wait;
|
||||
reg rd_inc;
|
||||
|
||||
assign ready = valid && (addr == rd_addr) && rd_valid;
|
||||
wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
|
||||
|
||||
reg softreset;
|
||||
|
||||
reg config_en; // cfgreg[31]
|
||||
reg config_ddr; // cfgreg[22]
|
||||
reg config_qspi; // cfgreg[21]
|
||||
reg config_cont; // cfgreg[20]
|
||||
reg [3:0] config_dummy; // cfgreg[19:16]
|
||||
reg [3:0] config_oe; // cfgreg[11:8]
|
||||
reg config_csb; // cfgreg[5]
|
||||
reg config_clk; // cfgref[4]
|
||||
reg [3:0] config_do; // cfgreg[3:0]
|
||||
|
||||
assign cfgreg_do[31] = config_en;
|
||||
assign cfgreg_do[30:23] = 0;
|
||||
assign cfgreg_do[22] = config_ddr;
|
||||
assign cfgreg_do[21] = config_qspi;
|
||||
assign cfgreg_do[20] = config_cont;
|
||||
assign cfgreg_do[19:16] = config_dummy;
|
||||
assign cfgreg_do[15:12] = 0;
|
||||
assign cfgreg_do[11:8] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
|
||||
assign cfgreg_do[7:6] = 0;
|
||||
assign cfgreg_do[5] = flash_csb;
|
||||
assign cfgreg_do[4] = flash_clk;
|
||||
assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
|
||||
|
||||
always @(posedge clk) begin
|
||||
softreset <= !config_en || cfgreg_we;
|
||||
if (!resetn) begin
|
||||
softreset <= 1;
|
||||
config_en <= 1;
|
||||
config_csb <= 0;
|
||||
config_clk <= 0;
|
||||
config_oe <= 0;
|
||||
config_do <= 0;
|
||||
config_ddr <= 0;
|
||||
config_qspi <= 0;
|
||||
config_cont <= 0;
|
||||
config_dummy <= 8;
|
||||
end else begin
|
||||
if (cfgreg_we[0]) begin
|
||||
config_csb <= cfgreg_di[5];
|
||||
config_clk <= cfgreg_di[4];
|
||||
config_do <= cfgreg_di[3:0];
|
||||
end
|
||||
if (cfgreg_we[1]) begin
|
||||
config_oe <= cfgreg_di[11:8];
|
||||
end
|
||||
if (cfgreg_we[2]) begin
|
||||
config_ddr <= cfgreg_di[22];
|
||||
config_qspi <= cfgreg_di[21];
|
||||
config_cont <= cfgreg_di[20];
|
||||
config_dummy <= cfgreg_di[19:16];
|
||||
end
|
||||
if (cfgreg_we[3]) begin
|
||||
config_en <= cfgreg_di[31];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire xfer_csb;
|
||||
wire xfer_clk;
|
||||
|
||||
wire xfer_io0_oe;
|
||||
wire xfer_io1_oe;
|
||||
wire xfer_io2_oe;
|
||||
wire xfer_io3_oe;
|
||||
|
||||
wire xfer_io0_do;
|
||||
wire xfer_io1_do;
|
||||
wire xfer_io2_do;
|
||||
wire xfer_io3_do;
|
||||
|
||||
reg xfer_io0_90;
|
||||
reg xfer_io1_90;
|
||||
reg xfer_io2_90;
|
||||
reg xfer_io3_90;
|
||||
|
||||
always @(negedge clk) begin
|
||||
xfer_io0_90 <= xfer_io0_do;
|
||||
xfer_io1_90 <= xfer_io1_do;
|
||||
xfer_io2_90 <= xfer_io2_do;
|
||||
xfer_io3_90 <= xfer_io3_do;
|
||||
end
|
||||
|
||||
assign flash_csb = config_en ? xfer_csb : config_csb;
|
||||
assign flash_clk = config_en ? xfer_clk : config_clk;
|
||||
|
||||
assign flash_io0_oe = config_en ? xfer_io0_oe : config_oe[0];
|
||||
assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
|
||||
assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
|
||||
assign flash_io3_oe = config_en ? xfer_io3_oe : config_oe[3];
|
||||
|
||||
assign flash_io0_do = config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0];
|
||||
assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1];
|
||||
assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2];
|
||||
assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3];
|
||||
|
||||
wire xfer_dspi = din_ddr && !din_qspi;
|
||||
wire xfer_ddr = din_ddr && din_qspi;
|
||||
|
||||
spimemio_xfer xfer (
|
||||
.clk (clk ),
|
||||
.resetn (xfer_resetn ),
|
||||
.din_valid (din_valid ),
|
||||
.din_ready (din_ready ),
|
||||
.din_data (din_data ),
|
||||
.din_tag (din_tag ),
|
||||
.din_cont (din_cont ),
|
||||
.din_dspi (xfer_dspi ),
|
||||
.din_qspi (din_qspi ),
|
||||
.din_ddr (xfer_ddr ),
|
||||
.din_rd (din_rd ),
|
||||
.dout_valid (dout_valid ),
|
||||
.dout_data (dout_data ),
|
||||
.dout_tag (dout_tag ),
|
||||
.flash_csb (xfer_csb ),
|
||||
.flash_clk (xfer_clk ),
|
||||
.flash_io0_oe (xfer_io0_oe ),
|
||||
.flash_io1_oe (xfer_io1_oe ),
|
||||
.flash_io2_oe (xfer_io2_oe ),
|
||||
.flash_io3_oe (xfer_io3_oe ),
|
||||
.flash_io0_do (xfer_io0_do ),
|
||||
.flash_io1_do (xfer_io1_do ),
|
||||
.flash_io2_do (xfer_io2_do ),
|
||||
.flash_io3_do (xfer_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)
|
||||
);
|
||||
|
||||
reg [3:0] state;
|
||||
|
||||
always @(posedge clk) begin
|
||||
xfer_resetn <= 1;
|
||||
din_valid <= 0;
|
||||
|
||||
if (!resetn || softreset) begin
|
||||
state <= 0;
|
||||
xfer_resetn <= 0;
|
||||
rd_valid <= 0;
|
||||
din_tag <= 0;
|
||||
din_cont <= 0;
|
||||
din_qspi <= 0;
|
||||
din_ddr <= 0;
|
||||
din_rd <= 0;
|
||||
end else begin
|
||||
if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data;
|
||||
if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data;
|
||||
if (dout_valid && dout_tag == 3) buffer[23:16] <= dout_data;
|
||||
if (dout_valid && dout_tag == 4) begin
|
||||
rdata <= {dout_data, buffer};
|
||||
rd_addr <= rd_inc ? rd_addr + 4 : addr;
|
||||
rd_valid <= 1;
|
||||
rd_wait <= rd_inc;
|
||||
rd_inc <= 1;
|
||||
end
|
||||
|
||||
if (valid)
|
||||
rd_wait <= 0;
|
||||
|
||||
case (state)
|
||||
0: begin
|
||||
din_valid <= 1;
|
||||
din_data <= 8'h ff;
|
||||
din_tag <= 0;
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 1;
|
||||
end
|
||||
end
|
||||
1: begin
|
||||
if (dout_valid) begin
|
||||
xfer_resetn <= 0;
|
||||
state <= 2;
|
||||
end
|
||||
end
|
||||
2: begin
|
||||
din_valid <= 1;
|
||||
din_data <= 8'h ab;
|
||||
din_tag <= 0;
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 3;
|
||||
end
|
||||
end
|
||||
3: begin
|
||||
if (dout_valid) begin
|
||||
xfer_resetn <= 0;
|
||||
state <= 4;
|
||||
end
|
||||
end
|
||||
4: begin
|
||||
rd_inc <= 0;
|
||||
din_valid <= 1;
|
||||
din_tag <= 0;
|
||||
case ({config_ddr, config_qspi})
|
||||
2'b11: din_data <= 8'h ED;
|
||||
2'b01: din_data <= 8'h EB;
|
||||
2'b10: din_data <= 8'h BB;
|
||||
2'b00: din_data <= 8'h 03;
|
||||
endcase
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 5;
|
||||
end
|
||||
end
|
||||
5: begin
|
||||
if (valid && !ready) begin
|
||||
din_valid <= 1;
|
||||
din_tag <= 0;
|
||||
din_data <= addr[23:16];
|
||||
din_qspi <= config_qspi;
|
||||
din_ddr <= config_ddr;
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 6;
|
||||
end
|
||||
end
|
||||
end
|
||||
6: begin
|
||||
din_valid <= 1;
|
||||
din_tag <= 0;
|
||||
din_data <= addr[15:8];
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 7;
|
||||
end
|
||||
end
|
||||
7: begin
|
||||
din_valid <= 1;
|
||||
din_tag <= 0;
|
||||
din_data <= addr[7:0];
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
din_data <= 0;
|
||||
state <= config_qspi || config_ddr ? 8 : 9;
|
||||
end
|
||||
end
|
||||
8: begin
|
||||
din_valid <= 1;
|
||||
din_tag <= 0;
|
||||
din_data <= config_cont ? 8'h A5 : 8'h FF;
|
||||
if (din_ready) begin
|
||||
din_rd <= 1;
|
||||
din_data <= config_dummy;
|
||||
din_valid <= 0;
|
||||
state <= 9;
|
||||
end
|
||||
end
|
||||
9: begin
|
||||
din_valid <= 1;
|
||||
din_tag <= 1;
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 10;
|
||||
end
|
||||
end
|
||||
10: begin
|
||||
din_valid <= 1;
|
||||
din_data <= 8'h 00;
|
||||
din_tag <= 2;
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 11;
|
||||
end
|
||||
end
|
||||
11: begin
|
||||
din_valid <= 1;
|
||||
din_tag <= 3;
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 12;
|
||||
end
|
||||
end
|
||||
12: begin
|
||||
if (!rd_wait || valid) begin
|
||||
din_valid <= 1;
|
||||
din_tag <= 4;
|
||||
if (din_ready) begin
|
||||
din_valid <= 0;
|
||||
state <= 9;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
if (jump) begin
|
||||
rd_inc <= 0;
|
||||
rd_valid <= 0;
|
||||
xfer_resetn <= 0;
|
||||
if (config_cont) begin
|
||||
state <= 5;
|
||||
end else begin
|
||||
state <= 4;
|
||||
din_qspi <= 0;
|
||||
din_ddr <= 0;
|
||||
end
|
||||
din_rd <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module spimemio_xfer (
|
||||
input clk, resetn,
|
||||
|
||||
input din_valid,
|
||||
output din_ready,
|
||||
input [7:0] din_data,
|
||||
input [3:0] din_tag,
|
||||
input din_cont,
|
||||
input din_dspi,
|
||||
input din_qspi,
|
||||
input din_ddr,
|
||||
input din_rd,
|
||||
|
||||
output dout_valid,
|
||||
output [7:0] dout_data,
|
||||
output [3:0] dout_tag,
|
||||
|
||||
output reg flash_csb,
|
||||
output reg flash_clk,
|
||||
|
||||
output reg flash_io0_oe,
|
||||
output reg flash_io1_oe,
|
||||
output reg flash_io2_oe,
|
||||
output reg flash_io3_oe,
|
||||
|
||||
output reg flash_io0_do,
|
||||
output reg flash_io1_do,
|
||||
output reg flash_io2_do,
|
||||
output reg flash_io3_do,
|
||||
|
||||
input flash_io0_di,
|
||||
input flash_io1_di,
|
||||
input flash_io2_di,
|
||||
input flash_io3_di
|
||||
);
|
||||
reg [7:0] obuffer;
|
||||
reg [7:0] ibuffer;
|
||||
|
||||
reg [3:0] count;
|
||||
reg [3:0] dummy_count;
|
||||
|
||||
reg xfer_cont;
|
||||
reg xfer_dspi;
|
||||
reg xfer_qspi;
|
||||
reg xfer_ddr;
|
||||
reg xfer_ddr_q;
|
||||
reg xfer_rd;
|
||||
reg [3:0] xfer_tag;
|
||||
reg [3:0] xfer_tag_q;
|
||||
|
||||
reg [7:0] next_obuffer;
|
||||
reg [7:0] next_ibuffer;
|
||||
reg [3:0] next_count;
|
||||
|
||||
reg fetch;
|
||||
reg next_fetch;
|
||||
reg last_fetch;
|
||||
|
||||
always @(posedge clk) begin
|
||||
xfer_ddr_q <= xfer_ddr;
|
||||
xfer_tag_q <= xfer_tag;
|
||||
end
|
||||
|
||||
assign din_ready = din_valid && resetn && next_fetch;
|
||||
|
||||
assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && resetn;
|
||||
assign dout_data = ibuffer;
|
||||
assign dout_tag = xfer_tag_q;
|
||||
|
||||
always @* begin
|
||||
flash_io0_oe = 0;
|
||||
flash_io1_oe = 0;
|
||||
flash_io2_oe = 0;
|
||||
flash_io3_oe = 0;
|
||||
|
||||
flash_io0_do = 0;
|
||||
flash_io1_do = 0;
|
||||
flash_io2_do = 0;
|
||||
flash_io3_do = 0;
|
||||
|
||||
next_obuffer = obuffer;
|
||||
next_ibuffer = ibuffer;
|
||||
next_count = count;
|
||||
next_fetch = 0;
|
||||
|
||||
if (dummy_count == 0) begin
|
||||
casez ({xfer_ddr, xfer_qspi, xfer_dspi})
|
||||
3'b 000: begin
|
||||
flash_io0_oe = 1;
|
||||
flash_io0_do = obuffer[7];
|
||||
|
||||
if (flash_clk) begin
|
||||
next_obuffer = {obuffer[6:0], 1'b 0};
|
||||
next_count = count - |count;
|
||||
end else begin
|
||||
next_ibuffer = {ibuffer[6:0], flash_io1_di};
|
||||
end
|
||||
|
||||
next_fetch = (next_count == 0);
|
||||
end
|
||||
3'b 01?: begin
|
||||
flash_io0_oe = !xfer_rd;
|
||||
flash_io1_oe = !xfer_rd;
|
||||
flash_io2_oe = !xfer_rd;
|
||||
flash_io3_oe = !xfer_rd;
|
||||
|
||||
flash_io0_do = obuffer[4];
|
||||
flash_io1_do = obuffer[5];
|
||||
flash_io2_do = obuffer[6];
|
||||
flash_io3_do = obuffer[7];
|
||||
|
||||
if (flash_clk) begin
|
||||
next_obuffer = {obuffer[3:0], 4'b 0000};
|
||||
next_count = count - {|count, 2'b00};
|
||||
end else begin
|
||||
next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
|
||||
end
|
||||
|
||||
next_fetch = (next_count == 0);
|
||||
end
|
||||
3'b 11?: begin
|
||||
flash_io0_oe = !xfer_rd;
|
||||
flash_io1_oe = !xfer_rd;
|
||||
flash_io2_oe = !xfer_rd;
|
||||
flash_io3_oe = !xfer_rd;
|
||||
|
||||
flash_io0_do = obuffer[4];
|
||||
flash_io1_do = obuffer[5];
|
||||
flash_io2_do = obuffer[6];
|
||||
flash_io3_do = obuffer[7];
|
||||
|
||||
next_obuffer = {obuffer[3:0], 4'b 0000};
|
||||
next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
|
||||
next_count = count - {|count, 2'b00};
|
||||
|
||||
next_fetch = (next_count == 0);
|
||||
end
|
||||
3'b ??1: begin
|
||||
flash_io0_oe = !xfer_rd;
|
||||
flash_io1_oe = !xfer_rd;
|
||||
|
||||
flash_io0_do = obuffer[6];
|
||||
flash_io1_do = obuffer[7];
|
||||
|
||||
if (flash_clk) begin
|
||||
next_obuffer = {obuffer[5:0], 2'b 00};
|
||||
next_count = count - {|count, 1'b0};
|
||||
end else begin
|
||||
next_ibuffer = {ibuffer[5:0], flash_io1_di, flash_io0_di};
|
||||
end
|
||||
|
||||
next_fetch = (next_count == 0);
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
fetch <= 1;
|
||||
last_fetch <= 1;
|
||||
flash_csb <= 1;
|
||||
flash_clk <= 0;
|
||||
count <= 0;
|
||||
dummy_count <= 0;
|
||||
xfer_tag <= 0;
|
||||
xfer_cont <= 0;
|
||||
xfer_dspi <= 0;
|
||||
xfer_qspi <= 0;
|
||||
xfer_ddr <= 0;
|
||||
xfer_rd <= 0;
|
||||
end else begin
|
||||
fetch <= next_fetch;
|
||||
last_fetch <= xfer_ddr ? fetch : 1;
|
||||
if (dummy_count) begin
|
||||
flash_clk <= !flash_clk && !flash_csb;
|
||||
dummy_count <= dummy_count - flash_clk;
|
||||
end else
|
||||
if (count) begin
|
||||
flash_clk <= !flash_clk && !flash_csb;
|
||||
obuffer <= next_obuffer;
|
||||
ibuffer <= next_ibuffer;
|
||||
count <= next_count;
|
||||
end
|
||||
if (din_valid && din_ready) begin
|
||||
flash_csb <= 0;
|
||||
flash_clk <= 0;
|
||||
|
||||
count <= 8;
|
||||
dummy_count <= din_rd ? din_data : 0;
|
||||
obuffer <= din_data;
|
||||
|
||||
xfer_tag <= din_tag;
|
||||
xfer_cont <= din_cont;
|
||||
xfer_dspi <= din_dspi;
|
||||
xfer_qspi <= din_qspi;
|
||||
xfer_ddr <= din_ddr;
|
||||
xfer_rd <= din_rd;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user