`include "FRAM_Controller.sv"

module spi(bus.spi_port b, fram_if.fram_port_top i);
  parameter ringbuffer_size = 256;
  
  logic [19:0] FRAM_Adr;
  logic [7:0] FRAM_DATA_OUT;
  logic [7:0] FRAM_DATA_IN;
  logic FRAM_RW;
  logic FRAM_RSTATUS;
  logic FRAM_hbn;
  logic FRAM_go;
  logic FRAM_busy;
  
  logic [7:0] clk_cntr;

  initial begin    
    FRAM_Adr <= 20'h0;
    FRAM_DATA_IN <= 8'h0;
  	FRAM_RW = 0;
  	FRAM_RSTATUS = 0;
  	FRAM_hbn = 0;
  	FRAM_go = 0;
    clk_cntr = 0;
  end
  
  always @ (posedge b.timer) begin
    if(b.dip[0] == 0) begin  //Reset
      FRAM_Adr <= 20'h0;
      FRAM_DATA_IN <= 8'h0;
      FRAM_RW = 0;
      FRAM_RSTATUS = 0;
      FRAM_hbn = 0;
      FRAM_go = 0;
      clk_cntr = 0;
    end
    else if(b.dip[1] == 1) begin //Read
      FRAM_Adr <= (FRAM_Adr - 1) % (ringbuffer_size - 1);
      FRAM_RW <= 1'h1; //Read
      FRAM_go <= 1'h1; //Go
    end 
    else if(b.dip[1] == 0) begin //Write
      FRAM_Adr <= (FRAM_Adr + 1) % (ringbuffer_size - 1);
      FRAM_DATA_IN <= {6'h0, b.dip[4:3]};
      FRAM_RW <= 1'h0; //Write Operation
      FRAM_go <= 1'h1; //Go
    end      
  end
  
  always @ (posedge b.oszi_clk) begin
    if(FRAM_go == 1) 
      clk_cntr <= clk_cntr + 1;
    
    if(clk_cntr > 50 && FRAM_RW == 1'h1) begin
      b.spi_read <= FRAM_DATA_OUT[1:0];
      FRAM_go <= 1'h0;
      FRAM_RW <= 1'h0; 
      clk_cntr <= 0;
    end
    else if(clk_cntr > 50 && FRAM_RW == 1'h0) begin
      FRAM_go <= 1'h0;
      clk_cntr <= 0;
    end
  end
  
  
    FRAM FRAM_ut(
    .i_clk(b.oszi_clk),
    .i_nreset(b.dip[0]),
    .i_adr(FRAM_Adr),
    .i_data(FRAM_DATA_IN),
    .o_data(FRAM_DATA_OUT),
    .i_rw(FRAM_RW),
    .i_status(FRAM_RSTATUS),
    .i_hbn(FRAM_hbn),
    .i_cready(FRAM_go),
    .o_busy(FRAM_busy),
    .o_SPI_Clk(i.sclk),
    .i_SPI_MISO(i.mosi),
    .o_SPI_MOSI(i.mosi), 
    .o_SPI_CS_n(i.ss)
  );
  
endmodule