diff --git a/Makefile b/Makefile index bafbb82..692704e 100644 --- a/Makefile +++ b/Makefile @@ -50,17 +50,13 @@ 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 \ - 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_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 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 diff --git a/core_dram_tb.vhdl b/core_dram_tb.vhdl index 3f95775..d72b1e7 100644 --- a/core_dram_tb.vhdl +++ b/core_dram_tb.vhdl @@ -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, diff --git a/core_flash_tb.vhdl b/core_flash_tb.vhdl new file mode 100644 index 0000000..6575aa5 --- /dev/null +++ b/core_flash_tb.vhdl @@ -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; diff --git a/sim_no_flash.vhdl b/sim_no_flash.vhdl new file mode 100644 index 0000000..9113c69 --- /dev/null +++ b/sim_no_flash.vhdl @@ -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;