From 8bc250d3fe49806f51044b811b92d06678a78a31 Mon Sep 17 00:00:00 2001
From: "Wesley W. Terpstra" <w.terpstra@gsi.de>
Date: Wed, 18 Sep 2013 17:52:29 +0200
Subject: [PATCH] spi flash: fix two off-by-one bugs that were cancelling out

c_status_time was one cycle longer than it should be!
this led to the arria5 requiring g_dummy_time-1 in c_vstatus_data
==> after fixing: must increase g_input_to_output_cycles on arria5

there was also a wrong calculation for s_wip with single-lane mode
it was working also by luck because WEL and WIP are usually set
together and are side-by-side, thus masking the c_status_time bug.
---
 modules/wishbone/wb_spi_flash/wb_spi_flash.vhd | 17 ++++++++++-------
 modules/wishbone/wishbone_pkg.vhd              |  2 +-
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/modules/wishbone/wb_spi_flash/wb_spi_flash.vhd b/modules/wishbone/wb_spi_flash/wb_spi_flash.vhd
index 72f869e3..3f215b0b 100644
--- a/modules/wishbone/wb_spi_flash/wb_spi_flash.vhd
+++ b/modules/wishbone/wb_spi_flash/wb_spi_flash.vhd
@@ -41,7 +41,7 @@ entity wb_spi_flash is
     --   a) slow clock, b) valid constraints, or c) registered in/outputs
     g_input_latch_edge       : std_logic := '1'; -- rising
     g_output_latch_edge      : std_logic := '0'; -- falling
-    g_input_to_output_cycles : natural   := 1);  -- between 1 and 32
+    g_input_to_output_cycles : natural   := 1);  -- between 1 and 8
   port(
     clk_i     : in  std_logic;
     rstn_i    : in  std_logic;
@@ -81,7 +81,7 @@ architecture rtl of wb_spi_flash is
   constant c_4addr        : t_byte := "10110111"; -- 
   constant c_3addr        : t_byte := "11101001"; -- 
   constant c_write_vstatus: t_byte := "10000001"; -- 
-  constant c_vstatus_data : t_byte := std_logic_vector(to_unsigned(g_dummy_time-1, 4)) & "1111"; -- no XIP (1), res (1), sequential read (11)
+  constant c_vstatus_data : t_byte := std_logic_vector(to_unsigned(g_dummy_time, 4)) & "1111"; -- no XIP (1), res (1), sequential read (11)
   
   function f_addr_bits(x : natural) return natural is begin
     if x <= 24 then return 24; else return 32; end if;
@@ -90,7 +90,7 @@ architecture rtl of wb_spi_flash is
   
   constant c_low_time    : t_count := to_unsigned(g_idle_time-1,                           t_count'length);
   constant c_cmd_time    : t_count := to_unsigned(t_byte'length-1,                         t_count'length);
-  constant c_status_time : t_count := to_unsigned(8*((g_input_to_output_cycles+14)/8),     t_count'length);
+  constant c_status_time : t_count := to_unsigned(8*((g_input_to_output_cycles+14)/8)-1,   t_count'length);
   constant c_addr_time   : t_count := to_unsigned((c_addr_bits/g_port_width)-1,            t_count'length);
   constant c_data_time   : t_count := to_unsigned((t_wishbone_data'length/g_port_width)-1, t_count'length);
 
@@ -184,6 +184,10 @@ begin
   assert (g_port_width = 1 or g_port_width = 2 or g_port_width = 4)
   report "g_port_width must be 1, 2, or 4, not " & integer'image(g_port_width)
   severity error;
+  
+  assert (g_input_to_output_cycles >= 1 and g_input_to_output_cycles <= 8)
+  report "g_input_to_output_cycles must be between 1 and 8, not " & integer'image(g_input_to_output_cycles)
+  severity error;
 
   crossing : xwb_clock_crossing
     port map(
@@ -429,12 +433,11 @@ begin
     end if;
   end process;
   
-  -- bit position 0 ... and correct when g_input_to_output_cycles=1
   wip1 : if g_port_width = 1 generate
-    s_wip <= r_shift_i((g_input_to_output_cycles+7) mod 8);
+    s_wip <= r_shift_i((9-g_input_to_output_cycles) mod 8);
   end generate;
   wipx : if g_port_width /= 1 generate
-    s_wip <= r_shift_i(((33-g_input_to_output_cycles) mod 8) * g_port_width + 1);
+    s_wip <= r_shift_i(((9-g_input_to_output_cycles) mod 8) * g_port_width + 1);
   end generate;
   
   main : process(clk_out_i, clk_out_rstn) is
@@ -538,7 +541,7 @@ begin
           r_adr     <= f_increment(r_adr);
         
         when S_READ_DUMMY =>
-          r_count <= to_unsigned(g_dummy_time-1, t_count'length);
+          r_count   <= to_unsigned(g_dummy_time-1, t_count'length);
           r_state_n <= S_READ_DATA;
         
         when S_READ_DATA =>
diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd
index 6d62fe9b..b34d1675 100644
--- a/modules/wishbone/wishbone_pkg.vhd
+++ b/modules/wishbone/wishbone_pkg.vhd
@@ -862,7 +862,7 @@ package wishbone_pkg is
       --   a) slow clock, b) valid constraints, or c) registered in/outputs
       g_input_latch_edge       : std_logic := '1'; -- rising
       g_output_latch_edge      : std_logic := '0'; -- falling
-      g_input_to_output_cycles : natural   := 1);  -- between 1 and 32
+      g_input_to_output_cycles : natural   := 1);  -- between 1 and 8
     port(
       clk_i     : in  std_logic;
       rstn_i    : in  std_logic;
-- 
GitLab