`timescale 10ns/10ns

module drv8353_spi_tb();

reg clk = 0;
reg rst = 1;
reg en = 0;

reg drv_fault_n = 1;
wire drv_en;

wire drv_cs_n;
wire drv_sck;
wire drv_sdi;
reg drv_sdo = 0;

// assert stop with the coast_nbrake
// bit to disable the gate drivers
reg stop = 0;
reg coast_nbrake = 0;
reg clear_fault = 0;

wire rdy;
wire fault_a;
wire fault_b;
wire fault_c;

drv8353r_driver #(0) dut(
  .clk(clk),
  .rst(rst),
  .en(en),

  .drv_fault_n(drv_fault_n),
  .drv_en(drv_en),

  .drv_cs_n(drv_cs_n),
  .drv_sck(drv_sck),
  .drv_sdi(drv_sdi),
  .drv_sdo(drv_sdo),

  .stop(stop),
  .coast_nbrake(coast_nbrake),
  .clear_fault(clear_fault),

  .rdy(rdy),
  .fault_a(fault_a),
  .fault_b(fault_b),
  .fault_c(fault_c)
);

integer cfg_num = -1;
integer cfg[5:0];
integer i = 0;
integer bit_count = 0;
reg spi_active = 0;

wire [15:0] cfg0;
wire [15:0] cfg1;
wire [15:0] cfg2;
wire [15:0] cfg3;
wire [15:0] cfg4;

assign cfg0 = cfg[0];
assign cfg1 = cfg[1];
assign cfg2 = cfg[2];
assign cfg3 = cfg[3];
assign cfg4 = cfg[4];

always @(negedge drv_cs_n) begin
  spi_active <= 1;
  cfg_num <= cfg_num + 1;
  if (drv_sck) begin
    $display("sck not low on falling edge, clock %d", i);
  end
end

always @(posedge drv_cs_n) begin
  spi_active <= 0;
  bit_count <= 0;
  if (drv_sck) begin
    $display("sck not low on rising edge, clock %d", i);
  end
end

always @(negedge drv_sck) begin
  if (drv_en & spi_active) begin
    cfg[cfg_num] <= cfg[cfg_num] << 1 | drv_sdi;
    bit_count <= bit_count + 1;
  end
end

integer j = 0;
integer expected = 0;
always @*
  case (j)
    0: expected = 16'b0010100000100000;
    1: expected = 16'b0011100001000010;
    2: expected = 16'b0100111101000010;
    3: expected = 16'b0101100101101101;
    4: expected = 16'b0110100010000011;
  endcase


always @(rdy) begin
  if (rdy) begin
    for (j = 0; j < 5; j += 1)
      #1
      if (cfg[j] != expected)
        $display("cfg %d bad, %x != %x", j, cfg[j], expected);
    $finish;
  end
end

initial begin
  $dumpfile("vcd/drv8353_spi_tb.vcd");
  $dumpvars;

  for (i = 0; i < 5; i += 1) cfg[i] = 0;
  // cycle the module long enough to get all the configuration bits
  // written out, and check to see if it worked correctly
  i = 0;

  #2 clk = 0;
  #2 clk = 1;

  i = i + 1;
  rst = 0;
  en = 1;

  for (i = 0; i < 3000; i+= 1) begin
    #2 clk = 0;
    #2 clk = 1;
    i = i + 1;
  end
end
 
endmodule