Commit 35ae1a29 authored by gilsoriano's avatar gilsoriano

Some modifications to spi to keep properly SPI1 latched once an operation is in progress.

Quick tests in m25p32. All the writing operations simulates properly.
parent 3ba1d86d
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -48,7 +48,7 @@ entity m25p32_regs is
g_ADDR_LENGTH : NATURAL := c_ADDR_LENGTH;
g_DATA_LENGTH : NATURAL := c_DATA_LENGTH;
g_READ_LENGTH : NATURAL := c_READ_LENGTH;
g_WB_ADDR_LENGTH : NATURAL := c_BYTES_PER_PAGE_BITS + 1);
g_WB_ADDR_LENGTH : NATURAL := c_WORDS_PER_PAGE_BITS + 1);
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
......@@ -59,22 +59,27 @@ entity m25p32_regs is
wb_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (g_WB_ADDR_LENGTH downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (g_WB_ADDR_LENGTH - 1 downto 0);
wb_ack_o : out STD_LOGIC;
wb_rty_o : out STD_LOGIC;
wb_err_o : out STD_LOGIC;
wr_data_o : out STD_LOGIC_VECTOR(g_DATA_LENGTH*8 - 1 downto 0);
rd_data_i : in STD_LOGIC_VECTOR(g_READ_LENGTH*8 - 1 downto 0);
SR_m25p32_o : out STD_LOGIC_VECTOR(r_SR_m25p32'a_length - 1 downto 0);
wr_data_o : out STD_LOGIC_VECTOR (g_DATA_LENGTH*8 - 1 downto 0);
rd_data_i : in STD_LOGIC_VECTOR (g_READ_LENGTH*8 - 1 downto 0);
SR_m25p32_o : out STD_LOGIC_VECTOR (r_SR_m25p32'a_length - 1 downto 0);
FMI_io : inout STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
OP_i : in STD_LOGIC_VECTOR (r_OP'a_length - 1 downto 0);
FMI_o : out STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
);
end m25p32_regs;
architecture Behavioral of m25p32_regs is
signal s_OP : r_OP;
signal s_FMI : r_FMI;
signal s_FMI_slv : STD_LOGIC_VECTOR(r_FMI'a_length - 1 downto 0);
signal s_SR_m25p32 : r_SR_m25p32;
signal s_wr_page : r_page;
......@@ -91,8 +96,10 @@ begin
wb_err_o <= s_wb_err_o;
wr_data_o <= f_STD_LOGIC_VECTOR(s_wr_page);
SR_m25p32_o <= f_STD_LOGIC_VECTOR(s_SR_m25p32);
FMI_io <= f_STD_LOGIC_VECTOR(s_FMI);
FMI_o <= f_STD_LOGIC_VECTOR(s_FMI);
s_OP <= f_OP(OP_i);
p_wbslave: process (wb_clk)
variable v_FMI : r_FMI;
......@@ -100,7 +107,8 @@ begin
begin
if rising_edge(wb_clk) then
if wb_rst_i = '1' then
s_FMI <= c_FMI_default;
s_FMI <= c_FMI_default;
s_SR_m25p32 <= c_SR_m25p32_default;
wb_data_o <= (others => '0');
s_wb_ack_o <= '0';
......@@ -108,6 +116,7 @@ begin
s_wb_err_o <= '0';
else
--! We never retry
s_wb_rty_o <= '0';
......@@ -119,14 +128,13 @@ begin
s_wb_ack_o <= '1';
s_wb_err_o <= '0';
if wb_we_i = '1' then
case wb_addr_i(g_WB_ADDR_LENGTH) is
case wb_addr_i(g_WB_ADDR_LENGTH - 1) is
when '0' =>
case wb_addr_i(1 downto 0) is
--! FMI address
when "00" =>
if s_FMI.OPA = '0' then
v_FMI := f_FMI(wb_data_i(23 downto 0));
s_FMI <= v_FMI;
if s_OP.OPA = '0' then
s_FMI <= f_FMI(wb_data_i(23 downto 0));
else
s_wb_ack_o <= '0';
s_wb_err_o <= '1';
......@@ -143,15 +151,18 @@ begin
--! WRITE_DATA address pool
when others =>
v_pos := to_integer(UNSIGNED(wb_addr_i(g_WB_ADDR_LENGTH
- 1 downto 0)));
- 2 downto 0)));
s_wr_page(v_pos).word_slv <= wb_data_i;
end case;
else
case wb_addr_i(g_WB_ADDR_LENGTH) is
case wb_addr_i(g_WB_ADDR_LENGTH - 1) is
when '0' =>
case wb_addr_i(1 downto 0) is
when "00" =>
wb_data_o(r_FMI'a_length - 1 downto 0) <= FMI_io;
wb_data_o(r_FMI'a_length - 1 downto 0)
<= f_STD_LOGIC_VECTOR(s_FMI);
wb_data_o(r_OP'a_length - 1 + 1 downto 1) <=
f_STD_LOGIC_VECTOR(s_OP);
wb_data_o(31 downto r_FMI'a_length)
<= (others => '0');
when "01" =>
......@@ -168,12 +179,17 @@ begin
when others =>
wb_data_o <= f_STD_LOGIC_VECTOR(
s_wr_page(to_integer(
UNSIGNED(wb_addr_i(g_WB_ADDR_LENGTH - 1 downto
UNSIGNED(wb_addr_i(g_WB_ADDR_LENGTH - 2 downto
0)))));
end case;
end if;
end if;
end if;
if s_OP.OPF = '1' then
s_FMI.OPR <= '0';
end if;
end if;
end if;
end process;
......
......@@ -40,6 +40,8 @@ use work.m25p32_pkg.ALL;
use work.spi_master_pkg.ALL;
entity m25p32_top is
generic(
g_WB_ADDR_LENGTH : NATURAL := c_WORDS_PER_PAGE_BITS + 1);
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
......@@ -50,7 +52,7 @@ entity m25p32_top is
wb_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (g_WB_ADDR_LENGTH - 1 downto 0);
wb_ack_o : out STD_LOGIC;
wb_rty_o : out STD_LOGIC;
wb_err_o : out STD_LOGIC;
......@@ -68,7 +70,8 @@ architecture Behavioral of m25p32_top is
signal s_rd_data : STD_LOGIC_VECTOR (c_READ_LENGTH*8 - 1 downto 0);
signal s_SR_m25p32 : STD_LOGIC_VECTOR (r_SR_m25p32'a_length - 1 downto 0);
signal s_FMI : STD_LOGIC_VECTOR ( r_FMI'a_length - 1 downto 0);
signal s_OP : STD_LOGIC_VECTOR (r_OP'a_length - 1 downto 0);
signal s_FMI : STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0);
component m25p32_core is
generic(
......@@ -85,11 +88,12 @@ architecture Behavioral of m25p32_top is
sclk_o : out STD_LOGIC;
ss_n_o : out STD_LOGIC;
wr_data_i : in STD_LOGIC_VECTOR(g_PAGE_SIZE*8 - 1 downto 0);
rd_data_o : out STD_LOGIC_VECTOR(g_READ_LENGTH*8 - 1 downto 0);
SR_m25p32_i : in STD_LOGIC_VECTOR(r_SR_m25p32'a_length - 1 downto 0);
wr_data_i : in STD_LOGIC_VECTOR (g_PAGE_SIZE*8 - 1 downto 0);
rd_data_o : out STD_LOGIC_VECTOR (g_READ_LENGTH*8 - 1 downto 0);
SR_m25p32_i : in STD_LOGIC_VECTOR (r_SR_m25p32'a_length - 1 downto 0);
FMI_io : inout STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
OP_o : out STD_LOGIC_VECTOR (r_OP'a_length - 1 downto 0);
FMI_i : in STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
);
end component;
......@@ -99,7 +103,7 @@ architecture Behavioral of m25p32_top is
g_ADDR_LENGTH : NATURAL := c_ADDR_LENGTH;
g_DATA_LENGTH : NATURAL := c_DATA_LENGTH;
g_READ_LENGTH : NATURAL := c_READ_LENGTH;
g_WB_ADDR_LENGTH : NATURAL := c_BYTES_PER_PAGE_BITS + 1);
g_WB_ADDR_LENGTH : NATURAL := c_WORDS_PER_PAGE_BITS + 1);
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
......@@ -110,21 +114,24 @@ architecture Behavioral of m25p32_top is
wb_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (g_WB_ADDR_LENGTH - 1 downto 0);
wb_ack_o : out STD_LOGIC;
wb_rty_o : out STD_LOGIC;
wb_err_o : out STD_LOGIC;
wr_data_o : out STD_LOGIC_VECTOR(g_DATA_LENGTH*8 - 1 downto 0);
rd_data_i : in STD_LOGIC_VECTOR(g_READ_LENGTH*8 - 1 downto 0);
SR_m25p32_o : out STD_LOGIC_VECTOR(r_SR_m25p32'a_length - 1 downto 0);
wr_data_o : out STD_LOGIC_VECTOR (g_DATA_LENGTH*8 - 1 downto 0);
rd_data_i : in STD_LOGIC_VECTOR (g_READ_LENGTH*8 - 1 downto 0);
FMI_io : inout STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
SR_m25p32_o : out STD_LOGIC_VECTOR (r_SR_m25p32'a_length - 1 downto 0);
OP_i : in STD_LOGIC_VECTOR (r_OP'a_length - 1 downto 0);
FMI_o : out STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
);
end component;
begin
inst_m25p32_core: m25p32_core
port map (
wb_rst_i => wb_rst_i,
......@@ -135,11 +142,12 @@ begin
sclk_o => prom_cclk_o,
ss_n_o => prom_cs0_b_n_o,
wr_data_i => s_wr_data,
rd_data_o => s_rd_data,
wr_data_i => s_wr_data,
rd_data_o => s_rd_data,
SR_m25p32_i => s_SR_m25p32,
FMI_io => s_FMI
OP_o => s_OP,
FMI_i => s_FMI
);
inst_m25p32_regs: m25p32_regs
......@@ -158,11 +166,12 @@ begin
wb_rty_o => wb_rty_o,
wb_err_o => wb_err_o,
wr_data_o => s_wr_data,
rd_data_i => s_rd_data,
wr_data_o => s_wr_data,
rd_data_i => s_rd_data,
SR_m25p32_o => s_SR_m25p32,
FMI_io => s_FMI
OP_i => s_OP,
FMI_o => s_FMI
);
end Behavioral;
This diff is collapsed.
......@@ -31,10 +31,16 @@ library work;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.spi_master_pkg.ALL;
use work.m25p32_pkg.ALL;
package m25p32_top_tb_pkg is
--! Constant only used in simulation
constant c_WISHBONE_PERIOD : TIME := 50 ns; --! Working at 20MHz
component m25p32_top is
generic(
g_WB_ADDR_LENGTH : NATURAL := c_WORDS_PER_PAGE_BITS + 1);
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
......@@ -45,7 +51,7 @@ package m25p32_top_tb_pkg is
wb_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (g_WB_ADDR_LENGTH - 1 downto 0);
wb_ack_o : out STD_LOGIC;
wb_rty_o : out STD_LOGIC;
wb_err_o : out STD_LOGIC;
......@@ -58,40 +64,49 @@ package m25p32_top_tb_pkg is
end component;
procedure wishbone_write (
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : out STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (3 downto 0);
reg_data : STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR (1 downto 0));
signal wb_clk : in STD_LOGIC;
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : out STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0);
reg_data : STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0));
procedure wishbone_read (
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : in STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (3 downto 0);
signal read_data : out STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR(1 downto 0));
signal wb_clk : in STD_LOGIC;
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : in STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0);
signal read_data : out STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0));
function fill_page return r_page;
end m25p32_top_tb_pkg;
package body m25p32_top_tb_pkg is
procedure wishbone_write (
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : out STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (3 downto 0);
reg_data : STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR (1 downto 0)) is
signal wb_clk : in STD_LOGIC;
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : out STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0);
reg_data : STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0)) is
begin
wait until rising_edge(wb_clk);
wb_we <= '1';
......@@ -110,14 +125,17 @@ package body m25p32_top_tb_pkg is
end procedure;
procedure wishbone_read (
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : in STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (3 downto 0);
signal read_data : out STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR(1 downto 0)) is
signal wb_clk : in STD_LOGIC;
signal wb_we : out STD_LOGIC;
signal wb_stb : out STD_LOGIC;
signal wb_cyc : out STD_LOGIC;
signal wb_sel : out STD_LOGIC_VECTOR (3 downto 0);
signal wb_data : in STD_LOGIC_VECTOR (31 downto 0);
signal wb_addr : out STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0);
signal read_data : out STD_LOGIC_VECTOR (31 downto 0);
reg_addr : STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0)) is
begin
wait until rising_edge(wb_clk);
wb_we <= '0';
......@@ -134,5 +152,26 @@ package body m25p32_top_tb_pkg is
wb_sel <= X"F";
end procedure;
function fill_page return r_page is
variable v_var0 : r_word := (word_slv => X"DEADBEEF");
variable v_var1 : r_word := (word_slv => X"8BADF00D");
variable v_var2 : r_word := (word_slv => X"C001F007");
variable v_var3 : r_word := (word_slv => X"B16B00B5");
variable v_return : r_page;
begin
for i in 0 to c_PAGE_SIZE/4 - 1 loop
case (i mod 4) is
when 0 =>
v_return(i) := v_var0;
when 1 =>
v_return(i) := v_var1;
when 2 =>
v_return(i) := v_var2;
when others =>
v_return(i) := v_var3;
end case;
end loop;
return v_return;
end function fill_page;
end m25p32_top_tb_pkg;
......@@ -702,6 +702,11 @@ begin
-----------------------------------------------------------
--! SPI mosi output
-----------------------------------------------------------
--! As FIFO dispatcher serves first the MSB, to keep
--! the consistency of the data, we will send first MSb,
--! which translates into sending first the bit 7 and last
--! the bit 0
-----------------------------------------------------------
p_spi_mosi_output :process(clk_i)
procedure mosi_update is
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment