diff options
Diffstat (limited to 'picosoc/spimemio.v')
-rw-r--r-- | picosoc/spimemio.v | 579 |
1 files changed, 0 insertions, 579 deletions
diff --git a/picosoc/spimemio.v b/picosoc/spimemio.v deleted file mode 100644 index b4ee446..0000000 --- a/picosoc/spimemio.v +++ /dev/null @@ -1,579 +0,0 @@ -/* - * PicoSoC - A simple example SoC using PicoRV32 - * - * Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.com> - * - * 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 |