module top ( input clk, output trap, input [31:0] gpio_i, output reg [31:0] gpio_o, output spi_cs, output spi_sclk, output spi_mosi, input spi_miso ); 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 wire mem_valid; wire mem_instr; reg mem_ready; wire [31:0] mem_addr; wire [31:0] mem_wdata; wire [3:0] mem_wstrb; reg [31:0] mem_rdata; wire spimem_ready; wire [31:0] spimem_rdata; 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_addr (mem_addr ), .mem_wdata (mem_wdata ), .mem_wstrb (mem_wstrb ), .mem_rdata (spimem_ready ? spimem_rdata : mem_rdata ) ); spimemio spimemio ( .clk(clk), .resetn(resetn), .valid (mem_valid && mem_addr[31:30] == 2'b10), .ready (spimem_ready), .addr (mem_addr[23:0]), .rdata (spimem_rdata), .spi_cs (spi_cs ), .spi_sclk (spi_sclk), .spi_mosi (spi_mosi), .spi_miso (spi_miso) ); 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 end end endmodule