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