initial commit
diff --git a/verilog/rtl/spimemio.v b/verilog/rtl/spimemio.v
index f5cc5c0..053aa61 100644
--- a/verilog/rtl/spimemio.v
+++ b/verilog/rtl/spimemio.v
@@ -17,585 +17,700 @@
*
*/
-module spimemio (
- input clk, resetn,
+module spimemio_wb (
+ input wb_clk_i,
+ input wb_rst_i,
- input valid,
- output ready,
- input [23:0] addr,
- output reg [31:0] rdata,
+ input [31:0] wb_adr_i,
+ input [31:0] wb_dat_i,
+ input [3:0] wb_sel_i,
+ input wb_we_i,
+ input wb_cyc_i,
- output flash_csb,
- output flash_clk,
+ input wb_flash_stb_i,
+ input wb_cfg_stb_i,
- output flash_csb_oeb,
- output flash_clk_oeb,
+ output wb_flash_ack_o,
+ output wb_cfg_ack_o,
- output flash_io0_oeb,
- output flash_io1_oeb,
- output flash_io2_oeb,
- output flash_io3_oeb,
+ output [31:0] wb_flash_dat_o,
+ output [31:0] wb_cfg_dat_o,
- output flash_csb_ieb,
- output flash_clk_ieb,
+ output flash_csb,
+ output flash_clk,
- output flash_io0_ieb,
- output flash_io1_ieb,
- output flash_io2_ieb,
- output flash_io3_ieb,
+ output flash_csb_oeb,
+ output flash_clk_oeb,
- output flash_io0_do,
- output flash_io1_do,
- output flash_io2_do,
- output flash_io3_do,
+ output flash_io0_oeb,
+ output flash_io1_oeb,
+ output flash_io2_oeb,
+ output flash_io3_oeb,
- input flash_io0_di,
- input flash_io1_di,
- input flash_io2_di,
- input flash_io3_di,
+ output flash_csb_ieb,
+ output flash_clk_ieb,
- input [3:0] cfgreg_we,
- input [31:0] cfgreg_di,
- output [31:0] cfgreg_do
+ output flash_io0_ieb,
+ output flash_io1_ieb,
+ output flash_io2_ieb,
+ output flash_io3_ieb,
+
+ 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
+
);
- 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 spimem_ready;
+ wire [23:0] mem_addr;
+ wire [31:0] spimem_rdata;
+ wire [31:0] spimemio_cfgreg_do;
+ wire [3:0] cfgreg_we;
+ wire spimemio_cfgreg_sel;
+ wire valid;
+ wire resetn;
- wire dout_valid;
- wire [7:0] dout_data;
- wire [3:0] dout_tag;
+ assign resetn = ~wb_rst_i;
+ assign valid = wb_cyc_i && wb_flash_stb_i;
+ assign wb_flash_ack_o = spimem_ready;
+ assign wb_cfg_ack_o = spimemio_cfgreg_sel;
- reg [23:0] buffer;
+ assign mem_addr = wb_adr_i[23:0];
+ assign spimemio_cfgreg_sel = wb_cyc_i && wb_cfg_stb_i;
- reg [23:0] rd_addr;
- reg rd_valid;
- reg rd_wait;
- reg rd_inc;
+ assign cfgreg_we = spimemio_cfgreg_sel ? wb_sel_i & {4{wb_we_i}} : 4'b 0000;
+ assign wb_flash_dat_o = spimem_rdata;
+ assign wb_cfg_dat_o = spimemio_cfgreg_do;
- assign ready = valid && (addr == rd_addr) && rd_valid;
- wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
+ spimemio spimemio (
+ .clk (wb_clk_i),
+ .resetn (resetn),
+ .valid (valid),
+ .ready (spimem_ready),
+ .addr (mem_addr),
+ .rdata (spimem_rdata),
- reg softreset;
+ .flash_csb (flash_csb),
+ .flash_clk (flash_clk),
- 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]
+ .flash_csb_oeb (flash_csb_oeb),
+ .flash_clk_oeb (flash_clk_oeb),
- 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_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb};
- 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};
+ .flash_io0_oeb (flash_io0_oeb),
+ .flash_io1_oeb (flash_io1_oeb),
+ .flash_io2_oeb (flash_io2_oeb),
+ .flash_io3_oeb (flash_io3_oeb),
- 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
+ .flash_csb_ieb (flash_csb_ieb),
+ .flash_clk_ieb (flash_clk_ieb),
- wire xfer_csb;
- wire xfer_clk;
+ .flash_io0_ieb (flash_io0_ieb),
+ .flash_io1_ieb (flash_io1_ieb),
+ .flash_io2_ieb (flash_io2_ieb),
+ .flash_io3_ieb (flash_io3_ieb),
- wire xfer_io0_oe;
- wire xfer_io1_oe;
- wire xfer_io2_oe;
- wire xfer_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),
- wire xfer_io0_do;
- wire xfer_io1_do;
- wire xfer_io2_do;
- wire 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 xfer_io0_90;
- reg xfer_io1_90;
- reg xfer_io2_90;
- reg xfer_io3_90;
+ .cfgreg_we(cfgreg_we),
+ .cfgreg_di(wb_dat_i),
+ .cfgreg_do(spimemio_cfgreg_do)
+ );
- 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
+endmodule
- assign flash_csb = config_en ? xfer_csb : config_csb;
- assign flash_clk = config_en ? xfer_clk : config_clk;
+module spimemio (
+ input clk, resetn,
- assign flash_csb_oeb = ~resetn;
- assign flash_clk_oeb = ~resetn;
+ input valid,
+ output ready,
+ input [23:0] addr,
+ output reg [31:0] rdata,
- assign flash_io0_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]);
- assign flash_io1_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]);
- assign flash_io2_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]);
- assign flash_io3_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]);
- assign flash_csb_ieb = 1'b1; /* Always disabled */
- assign flash_clk_ieb = 1'b1; /* Always disabled */
+ output flash_csb,
+ output flash_clk,
- assign flash_io0_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]);
- assign flash_io1_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
- assign flash_io2_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]);
- assign flash_io3_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io3_oe : config_oe[3]);
+ output flash_csb_oeb,
+ output flash_clk_oeb,
- 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];
+ output flash_io0_oeb,
+ output flash_io1_oeb,
+ output flash_io2_oeb,
+ output flash_io3_oeb,
- wire xfer_dspi = din_ddr && !din_qspi;
- wire xfer_ddr = din_ddr && din_qspi;
+ output flash_csb_ieb,
+ output flash_clk_ieb,
- spimemio_xfer xfer (
- .clk (clk ),
- .resetn (resetn ),
- .xfer_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)
- );
+ output flash_io0_ieb,
+ output flash_io1_ieb,
+ output flash_io2_ieb,
+ output flash_io3_ieb,
- reg [3:0] state;
+ output flash_io0_do,
+ output flash_io1_do,
+ output flash_io2_do,
+ output flash_io3_do,
- always @(posedge clk) begin
- xfer_resetn <= 1;
- din_valid <= 0;
+ input flash_io0_di,
+ input flash_io1_di,
+ input flash_io2_di,
+ input flash_io3_di,
- 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
+ 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;
- if (valid)
- rd_wait <= 0;
+ wire dout_valid;
+ wire [7:0] dout_data;
+ wire [3:0] dout_tag;
- 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
+ reg [23:0] buffer;
- 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
+ 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_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb};
+ 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_csb_oeb = ~resetn;
+ assign flash_clk_oeb = ~resetn;
+
+ assign flash_io0_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]);
+ assign flash_io1_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]);
+ assign flash_io2_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]);
+ assign flash_io3_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]);
+ assign flash_csb_ieb = 1'b1; /* Always disabled */
+ assign flash_clk_ieb = 1'b1; /* Always disabled */
+
+ assign flash_io0_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]);
+ assign flash_io1_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
+ assign flash_io2_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]);
+ assign flash_io3_ieb = ~resetn ? 1'b1 : (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 (resetn ),
+ .xfer_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, xfer_resetn,
+ input clk, resetn, xfer_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,
+ 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 dout_valid,
+ output [7:0] dout_data,
+ output [3:0] dout_tag,
- output reg flash_csb,
- output reg flash_clk,
+ 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_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,
+ 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
+ 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 [7:0] obuffer;
+ reg [7:0] ibuffer;
- reg [3:0] count;
- reg [3:0] dummy_count;
+ 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 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 [7:0] next_obuffer;
+ reg [7:0] next_ibuffer;
+ reg [3:0] next_count;
- reg fetch;
- reg next_fetch;
- reg last_fetch;
+ reg fetch;
+ reg next_fetch;
+ reg last_fetch;
- always @(posedge clk) begin
- xfer_ddr_q <= xfer_ddr;
- xfer_tag_q <= xfer_tag;
- end
+ always @(posedge clk) begin
+ xfer_ddr_q <= xfer_ddr;
+ xfer_tag_q <= xfer_tag;
+ end
- assign din_ready = din_valid && xfer_resetn && next_fetch;
+ assign din_ready = din_valid && xfer_resetn && next_fetch;
- assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_resetn;
- assign dout_data = ibuffer;
- assign dout_tag = xfer_tag_q;
+ assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_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;
+ 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;
+ 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;
+ 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 (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
+ 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;
+ 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];
+ 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
+ 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;
+ 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];
+ 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_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;
+ 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];
+ 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
+ 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
+ next_fetch = (next_count == 0);
+ end
+ endcase
+ end
+ end
- always @(posedge clk) begin
- if (!resetn || !xfer_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;
+ always @(posedge clk) begin
+ if (!resetn || !xfer_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;
+ 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
+ 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
+