 
`timescale 1ns / 1ps

module Flash_Interface (
  input reset,
  input clk,

  output reg [63:0] TraceID

);

  reg        wb_cyc;
  reg        wb_stb; 
  reg        wb_we;
  reg  [7:0] wb_addr;
  reg  [7:0] wb_wdat;
  wire [7:0] wb_rdat;
  wire       wb_ack;
  wire       wb_irq;

  reg [5:0] cnt;

  localparam RESET    = 2'd0;
  localparam CMD      = 2'd1;
  localparam ACK_WAIT = 2'd2;
  localparam DONE     = 2'd3;
  reg [1:0] state;

  task wb_write(
      input  [7:0] addr,
      input  [7:0] data
    );
    begin
      wb_addr <= addr;
      wb_wdat <= data;
      wb_cyc  <= 1'b1;
      wb_stb  <= 1'b1;
      wb_we   <= 1'b1;
    end
  endtask

  task wb_read(
      input  [7:0] addr
    );
    begin
      wb_addr <= addr;
      wb_cyc  <= 1'b1;
      wb_stb  <= 1'b1;
      wb_we   <= 1'b0;
    end
  endtask

  task wb_idle;
    begin
      wb_cyc <= 1'b0;
      wb_stb <= 1'b0;
      wb_we  <= 1'b0;
    end
  endtask


  always @(posedge clk) begin
    if (reset) begin
      TraceID <= 63'hDEADBEEF;
      state   <= RESET;
      cnt     <= 6'd1;
      wb_cyc  <= 1'b0;
      wb_stb  <= 1'b0; 
      wb_we   <= 1'b0;
      wb_addr <= 1'b0;
      wb_wdat <= 1'b0;
    end else
      case (state)
        RESET : begin
                  wb_idle;
                  cnt <= cnt + 5'd1;
                  if (cnt == 0) // Delay accesses following reset
                    state <= CMD;
                end

        CMD   : begin
                  cnt <= cnt + 5'd1;
                  state  <= ACK_WAIT;
                  case (cnt)
                    5'd1:  wb_write(8'h70, 8'h80);   // Write 0x80 to addr 0x70 (enable  Wishbone access to CFG)
                    5'd2:  wb_write(8'h71, 8'h19);   // Write 0x19 to addr 0x71 (Read traceID command)
                    5'd3,5'd4,5'd5:
                           wb_write(8'h71, 8'h0);    // Write 0x00 to addc 0x71 (3 dummy arguments)
                    5'd6,5'd7,5'd8,5'd9,5'd10,5'd11,5'd12,5'd13:
                           wb_read(8'h73);           // Read TraceID Addr 0x73 (TraceID[63:56])
                    5'd14: wb_write(8'h70, 8'h00);  // Disable Wishbone access to CFG
                    default: begin
                           wb_idle;
                           state <= DONE;
                    end
                  endcase
                end               

        ACK_WAIT: begin
                    if (wb_ack) begin
                       wb_idle;
                       state <= CMD;
                       if (~wb_we) TraceID <= {TraceID[55:0],wb_rdat};
                    end
                  end

        DONE : wb_idle;
      endcase
  end

  MACHXO3_EFB EFB_u (
    .wb_clk_i(clk),
    .wb_rst_i(reset),
    .wb_cyc_i(wb_cyc),
    .wb_stb_i(wb_stb), 
    .wb_we_i(wb_we),
    .wb_adr_i(wb_addr),
    .wb_dat_i(wb_wdat),
    .wb_dat_o(wb_rdat),
    .wb_ack_o(wb_ack)
	//,     .wbc_ufm_irq(wb_irq)
    );

endmodule  
  
