mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
spi: Add simulation support
This require the s25fl128s.vhd flash model and FMF libraries, which will be built when passed to the Makefile via the FLASH_MODEL_PATH argument. Otherwise a dummy module is used which ties MISO to '1'. The model isn't included as I'm not sure its licence (GPL) is at this point, but it can be obtained from https://github.com/ozbenh/microspi FLASH_MODEL_PATH=<path to microspi>/model Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
cc4dcb3597
commit
a89e1469ef
49
Makefile
49
Makefile
@ -50,18 +50,14 @@ core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \
|
||||
loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \
|
||||
core.vhdl
|
||||
|
||||
soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
|
||||
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl
|
||||
soc_files = $(core_files) wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
|
||||
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl \
|
||||
spi_rxtx.vhdl spi_flash_ctrl.vhdl
|
||||
|
||||
soc_sim_files = sim_console.vhdl sim_uart.vhdl sim_bram_helpers.vhdl \
|
||||
|
||||
soc_sim_files = $(soc_files) sim_console.vhdl sim_uart.vhdl sim_bram_helpers.vhdl \
|
||||
sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl
|
||||
|
||||
unisim_lib = sim-unisim/unisim-obj08.cf
|
||||
unisim_lib_files = sim-unisim/BSCANE2.vhdl sim-unisim/BUFG.vhdl \
|
||||
sim-unisim/unisim_vcomponents.vhdl
|
||||
$(unisim_lib): $(unisim_lib_files)
|
||||
ghdl -i --std=08 --work=unisim --workdir=sim-unisim $^
|
||||
|
||||
soc_sim_c_files = sim_vhpi_c.c sim_bram_helpers_c.c sim_console_c.c \
|
||||
sim_jtag_socket_c.c
|
||||
|
||||
@ -69,12 +65,39 @@ soc_sim_obj_files=$(soc_sim_c_files:.c=.o)
|
||||
comma := ,
|
||||
soc_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_sim_obj_files))
|
||||
|
||||
unisim_dir = sim-unisim
|
||||
unisim_lib = $(unisim_dir)/unisim-obj08.cf
|
||||
unisim_lib_files = $(unisim_dir)/BSCANE2.vhdl $(unisim_dir)/BUFG.vhdl \
|
||||
$(unisim_dir)/unisim_vcomponents.vhdl
|
||||
$(unisim_lib): $(unisim_lib_files)
|
||||
ghdl -i --std=08 --work=unisim --workdir=$(unisim_dir) $^
|
||||
GHDLFLAGS += -P$(unisim_dir)
|
||||
|
||||
core_tbs = multiply_tb divider_tb rotator_tb countzero_tb
|
||||
soc_tbs = core_tb icache_tb dcache_tb dmi_dtm_tb wishbone_bram_tb
|
||||
soc_flash_tbs = core_flash_tb
|
||||
soc_dram_tbs = dram_tb core_dram_tb
|
||||
|
||||
$(soc_tbs): %: $(core_files) $(soc_files) $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) -Psim-unisim $(soc_sim_link) $(core_files) $(soc_files) $(soc_sim_files) $@.vhdl -e $@
|
||||
ifneq ($(FLASH_MODEL_PATH),)
|
||||
fmf_dir = $(FLASH_MODEL_PATH)/fmf
|
||||
fmf_lib = $(fmf_dir)/fmf-obj08.cf
|
||||
fmf_lib_files = $(wildcard $(fmf_dir)/*.vhd)
|
||||
GHDLFLAGS += -P$(fmf_dir)
|
||||
$(fmf_lib): $(fmf_lib_files)
|
||||
ghdl -i --std=08 --work=fmf --workdir=$(fmf_dir) $^
|
||||
|
||||
flash_model_files=$(FLASH_MODEL_PATH)/s25fl128s.vhd
|
||||
flash_model_files: $(fmf_lib)
|
||||
else
|
||||
flash_model_files=sim_no_flash.vhdl
|
||||
fmf_lib=
|
||||
endif
|
||||
|
||||
$(soc_flash_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) $(fmf_lib) $(flash_model_files) %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(soc_sim_files) $(flash_model_files) $@.vhdl $(unisim_files) -e $@
|
||||
|
||||
$(soc_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(soc_sim_files) $@.vhdl -e $@
|
||||
|
||||
$(core_tbs): %: $(core_files) glibc_random.vhdl glibc_random_helpers.vhdl %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) $(core_files) glibc_random.vhdl glibc_random_helpers.vhdl $@.vhdl -e $@
|
||||
@ -106,8 +129,8 @@ soc_dram_sim_obj_files = $(soc_sim_obj_files) sim_litedram_c.o
|
||||
dram_link_files=-Wl,obj_dir/Vlitedram_core__ALL.a -Wl,obj_dir/verilated.o -Wl,obj_dir/verilated_vcd_c.o -Wl,-lstdc++
|
||||
soc_dram_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_dram_sim_obj_files)) $(dram_link_files)
|
||||
|
||||
$(soc_dram_tbs): %: $(core_files) $(soc_dram_files) $(soc_dram_sim_files) $(soc_dram_sim_obj_files) $(unisim_lib) %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) -Psim-unisim $(soc_dram_sim_link) $(core_files) $(soc_dram_files) $(soc_dram_sim_files) $@.vhdl -e $@
|
||||
$(soc_dram_tbs): %: $(soc_dram_files) $(soc_dram_sim_files) $(soc_dram_sim_obj_files) $(flash_model_files) $(unisim_lib) $(fmf_lib) %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) $(soc_dram_sim_link) $(soc_dram_files) $(soc_dram_sim_files) $(flash_model_files) $@.vhdl -e $@
|
||||
endif
|
||||
|
||||
# Hello world
|
||||
|
||||
@ -5,6 +5,7 @@ use ieee.numeric_std.all;
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.wishbone_types.all;
|
||||
use work.utils.all;
|
||||
|
||||
entity core_dram_tb is
|
||||
generic (
|
||||
@ -31,6 +32,17 @@ architecture behave of core_dram_tb is
|
||||
signal wb_dram_is_init : std_ulogic;
|
||||
signal core_alt_reset : std_ulogic;
|
||||
|
||||
-- SPI
|
||||
signal spi_sck : std_ulogic;
|
||||
signal spi_cs_n : std_ulogic := '1';
|
||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
||||
signal fl_hold_n : std_logic;
|
||||
signal fl_wp_n : std_logic;
|
||||
signal fl_mosi : std_logic;
|
||||
signal fl_miso : std_logic;
|
||||
|
||||
-- ROM size
|
||||
function get_rom_size return natural is
|
||||
begin
|
||||
@ -53,7 +65,10 @@ begin
|
||||
HAS_DRAM => true,
|
||||
DRAM_SIZE => 256 * 1024 * 1024,
|
||||
DRAM_INIT_SIZE => ROM_SIZE,
|
||||
CLK_FREQ => 100000000
|
||||
CLK_FREQ => 100000000,
|
||||
HAS_SPI_FLASH => true,
|
||||
SPI_FLASH_DLINES => 4,
|
||||
SPI_FLASH_OFFSET => 0
|
||||
)
|
||||
port map(
|
||||
rst => soc_rst,
|
||||
@ -66,9 +81,44 @@ begin
|
||||
wb_dram_ctrl_out => wb_dram_ctrl_out,
|
||||
wb_dram_is_csr => wb_dram_is_csr,
|
||||
wb_dram_is_init => wb_dram_is_init,
|
||||
spi_flash_sck => spi_sck,
|
||||
spi_flash_cs_n => spi_cs_n,
|
||||
spi_flash_sdat_o => spi_sdat_o,
|
||||
spi_flash_sdat_oe => spi_sdat_oe,
|
||||
spi_flash_sdat_i => spi_sdat_i,
|
||||
alt_reset => core_alt_reset
|
||||
);
|
||||
|
||||
flash: entity work.s25fl128s
|
||||
generic map (
|
||||
TimingModel => "S25FL128SAGNFI000_R_30pF",
|
||||
LongTimming => false,
|
||||
tdevice_PU => 10 ns,
|
||||
tdevice_PP256 => 100 ns,
|
||||
tdevice_PP512 => 100 ns,
|
||||
tdevice_WRR => 100 ns,
|
||||
UserPreload => TRUE
|
||||
)
|
||||
port map(
|
||||
SCK => spi_sck,
|
||||
SI => fl_mosi,
|
||||
CSNeg => spi_cs_n,
|
||||
HOLDNeg => fl_hold_n,
|
||||
WPNeg => fl_wp_n,
|
||||
RSTNeg => '1',
|
||||
SO => fl_miso
|
||||
);
|
||||
|
||||
fl_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
||||
fl_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
||||
fl_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
||||
fl_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else '1' when spi_sdat_oe(0) = '1' else 'Z';
|
||||
|
||||
spi_sdat_i(0) <= fl_mosi;
|
||||
spi_sdat_i(1) <= fl_miso;
|
||||
spi_sdat_i(2) <= fl_wp_n;
|
||||
spi_sdat_i(3) <= fl_hold_n;
|
||||
|
||||
dram: entity work.litedram_wrapper
|
||||
generic map(
|
||||
DRAM_ABITS => 24,
|
||||
|
||||
119
core_flash_tb.vhdl
Normal file
119
core_flash_tb.vhdl
Normal file
@ -0,0 +1,119 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity core_flash_tb is
|
||||
end core_flash_tb;
|
||||
|
||||
architecture behave of core_flash_tb is
|
||||
signal clk, rst: std_logic;
|
||||
|
||||
-- testbench signals
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- Dummy DRAM
|
||||
signal wb_dram_in : wishbone_master_out;
|
||||
signal wb_dram_out : wishbone_slave_out;
|
||||
signal wb_dram_ctrl_in : wb_io_master_out;
|
||||
signal wb_dram_ctrl_out : wb_io_slave_out;
|
||||
|
||||
-- SPI
|
||||
signal spi_sck : std_ulogic;
|
||||
signal spi_cs_n : std_ulogic := '1';
|
||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
||||
signal fl_hold_n : std_logic;
|
||||
signal fl_wp_n : std_logic;
|
||||
signal fl_mosi : std_logic;
|
||||
signal fl_miso : std_logic;
|
||||
begin
|
||||
|
||||
soc0: entity work.soc
|
||||
generic map(
|
||||
SIM => true,
|
||||
MEMORY_SIZE => (384*1024),
|
||||
RAM_INIT_FILE => "main_ram.bin",
|
||||
RESET_LOW => false,
|
||||
CLK_FREQ => 100000000,
|
||||
HAS_SPI_FLASH => true,
|
||||
SPI_FLASH_DLINES => 4,
|
||||
SPI_FLASH_OFFSET => 0
|
||||
)
|
||||
port map(
|
||||
rst => rst,
|
||||
system_clk => clk,
|
||||
uart0_rxd => '0',
|
||||
uart0_txd => open,
|
||||
wb_dram_in => wb_dram_in,
|
||||
wb_dram_out => wb_dram_out,
|
||||
wb_dram_ctrl_in => wb_dram_ctrl_in,
|
||||
wb_dram_ctrl_out => wb_dram_ctrl_out,
|
||||
spi_flash_sck => spi_sck,
|
||||
spi_flash_cs_n => spi_cs_n,
|
||||
spi_flash_sdat_o => spi_sdat_o,
|
||||
spi_flash_sdat_oe => spi_sdat_oe,
|
||||
spi_flash_sdat_i => spi_sdat_i,
|
||||
alt_reset => '0'
|
||||
);
|
||||
|
||||
flash: entity work.s25fl128s
|
||||
generic map (
|
||||
TimingModel => "S25FL128SAGNFI000_R_30pF",
|
||||
LongTimming => false,
|
||||
tdevice_PU => 10 ns,
|
||||
tdevice_PP256 => 100 ns,
|
||||
tdevice_PP512 => 100 ns,
|
||||
tdevice_WRR => 100 ns
|
||||
)
|
||||
port map(
|
||||
SCK => spi_sck,
|
||||
SI => fl_mosi,
|
||||
CSNeg => spi_cs_n,
|
||||
HOLDNeg => fl_hold_n,
|
||||
WPNeg => fl_wp_n,
|
||||
RSTNeg => '1',
|
||||
SO => fl_miso
|
||||
);
|
||||
|
||||
fl_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
||||
fl_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
||||
fl_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
||||
fl_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else '1' when spi_sdat_oe(0) = '1' else 'Z';
|
||||
|
||||
spi_sdat_i(0) <= fl_mosi;
|
||||
spi_sdat_i(1) <= fl_miso;
|
||||
spi_sdat_i(2) <= fl_wp_n;
|
||||
spi_sdat_i(3) <= fl_hold_n;
|
||||
|
||||
clk_process: process
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
|
||||
rst_process: process
|
||||
begin
|
||||
rst <= '1';
|
||||
wait for 10*clk_period;
|
||||
rst <= '0';
|
||||
wait;
|
||||
end process;
|
||||
|
||||
jtag: entity work.sim_jtag;
|
||||
|
||||
-- Dummy DRAM
|
||||
wb_dram_out.ack <= wb_dram_in.cyc and wb_dram_in.stb;
|
||||
wb_dram_out.dat <= x"FFFFFFFFFFFFFFFF";
|
||||
wb_dram_out.stall <= '0';
|
||||
wb_dram_ctrl_out.ack <= wb_dram_ctrl_in.cyc and wb_dram_ctrl_in.stb;
|
||||
wb_dram_ctrl_out.dat <= x"FFFFFFFF";
|
||||
wb_dram_ctrl_out.stall <= '0';
|
||||
|
||||
end;
|
||||
28
sim_no_flash.vhdl
Normal file
28
sim_no_flash.vhdl
Normal file
@ -0,0 +1,28 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity s25fl128s is
|
||||
generic (
|
||||
LongTimming : boolean := true;
|
||||
TimingModel : string := "";
|
||||
tdevice_PU : time := 10 ns;
|
||||
tdevice_PP256 : time := 10 ns;
|
||||
tdevice_PP512 : time := 10 ns;
|
||||
tdevice_WRR : time := 10 ns;
|
||||
UserPreload : boolean := false
|
||||
);
|
||||
PORT (
|
||||
SI : inout std_ulogic := 'Z';
|
||||
SO : inout std_ulogic := 'Z';
|
||||
SCK : in std_ulogic := 'Z';
|
||||
CSNeg : in std_ulogic := 'Z';
|
||||
RSTNeg : in std_ulogic := 'Z';
|
||||
WPNeg : inout std_ulogic := 'Z';
|
||||
HOLDNeg : inout std_ulogic := 'Z'
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture behaviour of s25fl128s is
|
||||
begin
|
||||
SO <= '1';
|
||||
end architecture;
|
||||
Loading…
x
Reference in New Issue
Block a user