diff --git a/lib/spi/sim/tb_spi_flash_wb.fdo b/lib/spi/sim/tb_spi_flash_wb.fdo new file mode 100644 index 0000000..089e706 --- /dev/null +++ b/lib/spi/sim/tb_spi_flash_wb.fdo @@ -0,0 +1,30 @@ +## NOTE: Do not edit this file. +## Autogenerated by ProjNav (creatfdo.tcl) on Thu Jul 06 20:49:07 Westeuropäische Sommerzeit 2006 +## +if {[file exists work]} {vdel -lib work -all} + +vlib fmf +vcom -work fmf -93 "../../models/memory/flash/serial/S25fl064k/utilities/conversions.vhd" +vcom -work fmf -93 "../../models/memory/flash/serial/S25fl064k/utilities/gen_utils.vhd" + +vlib work +vcom -explicit -93 "../../misc/utils_pkg.vhd" +vcom -explicit -93 "../../FIFO/src/fifo_ctrl_pkg.vhd" +vcom -explicit -93 "../../rams/dpram_1w1r2c_ra_sim.vhd" +vcom -explicit -93 "../../FIFO/src/gray_counter.vhd" +vcom -explicit -93 "../../FIFO/src/fifo_async_ctrl.vhd" +vcom -explicit -93 "../../FIFO/src/fifo_async.vhd" +vcom -explicit -93 "../../FIFO/src/fifo_sync_ctrl.vhd" +vcom -explicit -93 "../../FIFO/src/fifo_sync.vhd" +vcom -explicit -93 "../src/spi_types.vhd" +vcom -explicit -93 "../src/spi_master.vhd" +vcom -explicit -93 "../src/spi_flash_wb.vhd" +vcom -explicit -93 "../../models/memory/flash/serial/S25fl064k/model/S25fl064k.vhd" +vcom -explicit -93 "../src/tb_spi_flash_wb.vhd" +vsim -t 1ps -lib work tb_spi_flash_wb +view wave +do {tb_spi_flash_wb.wdo} +view structure +view signals + +run 120 us diff --git a/lib/spi/sim/tb_spi_flash_wb.wdo b/lib/spi/sim/tb_spi_flash_wb.wdo new file mode 100644 index 0000000..bf6a524 --- /dev/null +++ b/lib/spi/sim/tb_spi_flash_wb.wdo @@ -0,0 +1,39 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -format Logic /tb_spi_flash_wb/clk +add wave -noupdate -format Logic /tb_spi_flash_wb/rst +add wave -noupdate -format Logic /tb_spi_flash_wb/cyc_i +add wave -noupdate -format Logic /tb_spi_flash_wb/stb_i +add wave -noupdate -format Literal /tb_spi_flash_wb/sel_i +add wave -noupdate -format Logic /tb_spi_flash_wb/we_i +add wave -noupdate -format Logic /tb_spi_flash_wb/ack_o +add wave -noupdate -format Logic /tb_spi_flash_wb/srdy_o +add wave -noupdate -format Logic /tb_spi_flash_wb/mrdy_i +add wave -noupdate -format Literal -radix hexadecimal /tb_spi_flash_wb/addr_i +add wave -noupdate -format Literal -radix hexadecimal /tb_spi_flash_wb/dat_i +add wave -noupdate -format Literal -radix hexadecimal /tb_spi_flash_wb/dat_o +add wave -noupdate -format Logic /tb_spi_flash_wb/int_o +add wave -noupdate -format Logic /tb_spi_flash_wb/mosi +add wave -noupdate -format Logic /tb_spi_flash_wb/miso +add wave -noupdate -format Logic /tb_spi_flash_wb/mst_clk +add wave -noupdate -format Logic /tb_spi_flash_wb/mso +add wave -noupdate -format Logic /tb_spi_flash_wb/mso_n +add wave -noupdate -format Logic /tb_spi_flash_wb/holdneg +add wave -noupdate -format Logic /tb_spi_flash_wb/wpneg +add wave -noupdate -format Logic /tb_spi_flash_wb/uut/register_access +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {20580000 ps} 0} +configure wave -namecolwidth 197 +configure wave -valuecolwidth 131 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {0 ps} {126 us} diff --git a/lib/spi/src/spi_flash_wb.vhd b/lib/spi/src/spi_flash_wb.vhd new file mode 100644 index 0000000..9b9bdc6 --- /dev/null +++ b/lib/spi/src/spi_flash_wb.vhd @@ -0,0 +1,177 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +LIBRARY WORK; +USE WORK.spi_types.all; + +ENTITY spi_flash_wb IS + Generic + ( + FLASH_ADDR_BITS : natural := 24; + CACHE_ADDR_BITS : natural := 8 + ); + Port + ( + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + INT_O : out STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + SEL_I : in unsigned(3 downto 0); + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + spi_hold : in std_logic; + spi_ss : out std_logic; + spi_clk : out std_logic; + spi_miso : in std_logic; + spi_mosi : out std_logic + ); +END spi_flash_wb; + +ARCHITECTURE rtl OF spi_flash_wb IS + + -- Signals for UART connections + signal mst_cmd : cmd_t; + signal mst_cmd_vld : std_logic; + signal mst_cmd_rdy : std_logic; + signal mst_shift_en : std_logic; + signal mst_din_vld : std_logic; + signal mst_din_rdy : std_logic; + + signal mst_ctrl : ctrl_t; + signal mst_status : status_t; + signal mst_din : unsigned(31 downto 0); + signal mst_dout : unsigned(31 downto 0); + signal mst_dout_re : std_logic; + signal mst_dout_vld : std_logic; + signal word_addr : unsigned(CACHE_ADDR_BITS-1 downto 0); + signal tag_reg : unsigned(FLASH_ADDR_BITS-1 downto CACHE_ADDR_BITS); + signal tag_valid : std_logic; + signal tag_match : std_logic; + signal cache_miss : std_logic; + signal register_access : std_logic; + +begin + mst_shift_en <= not spi_hold; + + SRDY_O <= CYC_I; + INT_O <= '0'; + + tag_match <= '1' when ADDR_I(tag_reg'range) = tag_reg else '0'; + cache_miss <= CYC_I and STB_I and not WE_I and not tag_match; + register_access <= CYC_I and STB_I and ADDR_I(FLASH_ADDR_BITS); + +inst_spi_master : entity work.spi_master + GENERIC MAP + ( + WORD_WIDTH => 32, + CAT_FIFO_DEPTH => 4, + DATA_FIFO_DEPTH => 4 + ) + PORT MAP + ( + rst => RST_I, + clk => CLK_I, + cmd_vld => mst_cmd_vld, + cmd_rdy => mst_cmd_rdy, + cmd => mst_cmd, + din_vld => mst_din_vld, + din_rdy => mst_din_rdy, + din => mst_din, + dout_re => mst_dout_re, + dout_vld => mst_dout_vld, + dout => mst_dout, + shift_en => mst_shift_en, + mosi => spi_mosi, + miso => spi_miso, + sclk => spi_clk, + mso => spi_ss, + ctrl => mst_ctrl, + status => mst_status + + ); + +------------------------------------------------------------------ +registers_write: + process(CLK_I) + begin + if rising_edge(CLK_I) then + mst_cmd_vld <= '0'; + mst_din_vld <= '0'; + if RST_I = '1' then + mst_ctrl.clk_div <= to_unsigned(100, 8); + mst_ctrl.cpol <= '0'; + mst_ctrl.cpha <= '0'; + mst_ctrl.msb_first <= '1'; + elsif (register_access and WE_I) = '1' then + case ADDR_I(5 downto 2) is + + when "0000" => + mst_cmd_vld <= DAT_I(0); + + when "0001" => + mst_cmd.xfer_size <= DAT_I; + + when "0010" => + mst_cmd.data_size <= DAT_I; + + when "0011" => + mst_din <= DAT_I; + mst_din_vld <= '1'; + + when "0100" => + mst_ctrl.clk_div <= DAT_I(7 downto 0); + mst_ctrl.cpol <= DAT_I(8); + mst_ctrl.cpha <= DAT_I(9); + mst_ctrl.msb_first <= DAT_I(10); + + when others => null; + end case; + end if; + end if; + end process; + +registers_read: + process(CLK_I) + begin + if rising_edge(CLK_I) then + mst_dout_re <= '0'; + ACK_O <= '0'; + if (register_access) = '1' then + ACK_O <= not WE_I; + DAT_O <= (others => '0'); + case ADDR_I(5 downto 2) is + + when "0000" => + DAT_O(2 downto 0) <= mst_dout_vld & mst_din_rdy & mst_cmd_rdy; + DAT_O(15 downto 8) <= spi_hold & mst_status.rx_valid & mst_status.read_fifo_empty & mst_status.read_fifo_full & mst_status.write_fifo_empty & mst_status.write_fifo_full & mst_status.cmd_fifo_empty & mst_status.cmd_fifo_full; + + when "0001" => + DAT_O <= mst_cmd.xfer_size; + + when "0010" => + DAT_O <= mst_cmd.data_size; + + when "0011" => + DAT_O <= mst_dout; + mst_dout_re <= not WE_I; + + when "0100" => + DAT_O(7 downto 0) <= mst_ctrl.clk_div; + DAT_O(8) <= mst_ctrl.cpol; + DAT_O(9) <= mst_ctrl.cpha; + DAT_O(10) <= mst_ctrl.msb_first; + + when others => null; + end case; + end if; + end if; + end process; + +end rtl; diff --git a/lib/spi/src/tb_spi_flash_wb.vhd b/lib/spi/src/tb_spi_flash_wb.vhd new file mode 100644 index 0000000..5f683f2 --- /dev/null +++ b/lib/spi/src/tb_spi_flash_wb.vhd @@ -0,0 +1,129 @@ +------------------------------------------------------------------------- +-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL +-- This file: testbench for system test using Xilinx ML-402 + +-- Copyright (C) 2007 J. Ahrensfeld + +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. + +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. + +-- You should have received a copy of the GNU Lesser General Public +-- License along with this library; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +-- For questions and ideas, please contact the author at jens@jayfield.org + +----------------------------------------------------------------------- + +LIBRARY ieee; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; + +use work.spi_types.all; + +ENTITY tb_spi_flash_wb IS +END tb_spi_flash_wb; + +ARCHITECTURE behavior OF tb_spi_flash_wb IS + + constant CLK_PERIOD : time := 20 ns; + + signal CLK : std_logic := '1'; + signal RST : std_logic := '1'; + signal CYC_I : STD_LOGIC := '0'; + signal STB_I : STD_LOGIC := '0'; + signal SEL_I : unsigned(3 downto 0) := "1111"; + signal WE_I : STD_LOGIC := '0'; + signal ACK_O : STD_LOGIC; + signal SRDY_O : STD_LOGIC; + signal MRDY_I : STD_LOGIC := '1'; + signal ADDR_I : unsigned(31 downto 0) := (others => '0'); + signal DAT_I : unsigned(31 downto 0) := (others => '0'); + signal DAT_O : unsigned(31 downto 0); + signal INT_O : STD_LOGIC; + + signal mosi : STD_LOGIC; + signal miso : STD_LOGIC := '0'; + signal mst_clk : STD_LOGIC; + signal mso : STD_LOGIC; + signal mso_n : STD_LOGIC; + signal HOLDNeg : STD_LOGIC := '1'; + signal WPNeg : STD_LOGIC := '1'; + +BEGIN + + mso_n <= not mso; + HOLDNeg <= '1'; + WPNeg <= '1'; + +uut : entity work.spi_flash_wb + PORT MAP + ( + CLK_I => CLK, + RST_I => RST, + CYC_I => CYC_I, + STB_I => STB_I, + SEL_I => SEL_I, + WE_I => WE_I, + ACK_O => ACK_O, + SRDY_O => SRDY_O, + MRDY_I => MRDY_I, + ADDR_I => ADDR_I, + DAT_I => DAT_I, + DAT_O => DAT_O, + INT_O => INT_O, + spi_hold => '0', + spi_clk => mst_clk, + spi_ss => mso, + spi_miso => miso, + spi_mosi => mosi + + ); + +inst_spi_slave: entity work.S25fl064k + PORT MAP ( + SCK => mst_clk, -- serial clock input + SI => mosi, -- serial data input + CSNeg => mso_n, -- chip select input + HOLDNeg => HOLDNeg, -- hold input + WPNeg => WPNeg, -- write protect input + SO => miso -- SO + ); + +CLK_GEN: process + begin + wait for CLK_PERIOD/2; + CLK <= not CLK; + end process; + +-- Master +STIMULUS: process + + + begin + + wait for 600*CLK_PERIOD; + RST <= '0'; + wait for 600*CLK_PERIOD; + + wait until rising_edge(CLK); + ADDR_I <= X"0100_0000"; + STB_I <= '1'; + CYC_I <= '1'; + wait until rising_edge(CLK) and SRDY_O = '1'; + STB_I <= '0'; + wait until rising_edge(CLK) and ACK_O = '1'; + CYC_I <= '0'; + + wait; + + end process; + +END;