mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-04-25 03:55:09 +00:00
litedram: Add simulation support
This adds a simulated litedram model along with the necessary Makefile gunk to verilate it and wrap it for use by ghdl. The core_dram_tb test bench is a variant of core_tb with LiteDRAM simulated. It's not built by default, an explicit make core_dram_tb is necessary as to not require verilator to be installed for the normal build process (also it's slow'ish). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
32
Makefile
32
Makefile
@@ -1,6 +1,6 @@
|
||||
GHDL ?= ghdl
|
||||
GHDLFLAGS=--std=08 --work=unisim
|
||||
CFLAGS=-O2 -Wall
|
||||
CFLAGS=-O3 -Wall
|
||||
|
||||
GHDLSYNTH ?= ghdl.so
|
||||
YOSYS ?= yosys
|
||||
@@ -66,6 +66,7 @@ soc_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_sim_obj_files))
|
||||
|
||||
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_dram_tbs = core_dram_tb
|
||||
|
||||
$(soc_tbs): %: $(core_files) $(soc_files) $(soc_sim_files) $(soc_sim_obj_files) %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(core_files) $(soc_files) $(soc_sim_files) $@.vhdl -e $@
|
||||
@@ -76,6 +77,34 @@ $(core_tbs): %: $(core_files) glibc_random.vhdl glibc_random_helpers.vhdl %.vhdl
|
||||
soc_reset_tb: fpga/soc_reset_tb.vhdl fpga/soc_reset.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) fpga/soc_reset_tb.vhdl fpga/soc_reset.vhdl -e $@
|
||||
|
||||
# LiteDRAM sim
|
||||
VERILATOR_ROOT=$(shell verilator -getenv VERILATOR_ROOT 2>/dev/null)
|
||||
ifeq (, $(VERILATOR_ROOT))
|
||||
$(soc_dram_tbs):
|
||||
$(error "Verilator is required to make this target !")
|
||||
else
|
||||
|
||||
VERILATOR_CFLAGS=-O3
|
||||
VERILATOR_FLAGS=-O3
|
||||
verilated_dram: litedram/generated/sim/litedram_core.v
|
||||
verilator $(VERILATOR_FLAGS) -CFLAGS $(VERILATOR_CFLAGS) -Wno-fatal --cc $< --trace
|
||||
make -C obj_dir -f ../litedram/extras/sim_dram_verilate.mk VERILATOR_ROOT=$(VERILATOR_ROOT)
|
||||
|
||||
SIM_DRAM_CFLAGS = -I. -Iobj_dir -Ilitedram/generated/sim -I$(VERILATOR_ROOT)/include -I$(VERILATOR_ROOT)/include/vltstd
|
||||
SIM_DRAM_CFLAGS += -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -DVL_PRINTF=printf -faligned-new
|
||||
sim_litedram_c.o: litedram/extras/sim_litedram_c.cpp verilated_dram
|
||||
$(CC) $(CPPFLAGS) $(SIM_DRAM_CFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
soc_dram_files = $(soc_files) litedram/extras/wrapper-mw-init.vhdl litedram/generated/sim/litedram-initmem.vhdl
|
||||
soc_dram_sim_files = $(soc_sim_files) litedram/extras/sim_litedram.vhdl
|
||||
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) %.vhdl
|
||||
$(GHDL) -c $(GHDLFLAGS) $(soc_dram_sim_link) $(core_files) $(soc_dram_files) $(soc_dram_sim_files) $@.vhdl -e $@
|
||||
endif
|
||||
|
||||
# Hello world
|
||||
MEMORY_SIZE=8192
|
||||
RAM_INIT_FILE=hello_world/hello_world.hex
|
||||
@@ -167,6 +196,7 @@ _clean:
|
||||
rm -f *.o work-*cf unisim-*cf $(all)
|
||||
rm -f fpga/*.o fpga/work-*cf
|
||||
rm -f sim-unisim/*.o sim-unisim/unisim-*cf
|
||||
rm -f litedram/extras/*.o
|
||||
rm -f TAGS
|
||||
rm -f scripts/mw_debug/*.o
|
||||
rm -f scripts/mw_debug/mw_debug
|
||||
|
||||
114
core_dram_tb.vhdl
Normal file
114
core_dram_tb.vhdl
Normal file
@@ -0,0 +1,114 @@
|
||||
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_dram_tb is
|
||||
end core_dram_tb;
|
||||
|
||||
architecture behave of core_dram_tb is
|
||||
signal clk, rst: std_logic;
|
||||
signal system_clk, soc_rst : std_ulogic;
|
||||
|
||||
-- testbench signals
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- Sim 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;
|
||||
signal wb_dram_is_csr : std_ulogic;
|
||||
signal wb_dram_is_init : std_ulogic;
|
||||
signal core_alt_reset : std_ulogic;
|
||||
begin
|
||||
|
||||
soc0: entity work.soc
|
||||
generic map(
|
||||
SIM => true,
|
||||
MEMORY_SIZE => (384*1024),
|
||||
RAM_INIT_FILE => "main_ram.bin",
|
||||
RESET_LOW => false,
|
||||
HAS_DRAM => true,
|
||||
DRAM_SIZE => 256 * 1024 * 1024,
|
||||
CLK_FREQ => 100000000
|
||||
)
|
||||
port map(
|
||||
rst => soc_rst,
|
||||
system_clk => system_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,
|
||||
wb_dram_is_csr => wb_dram_is_csr,
|
||||
wb_dram_is_init => wb_dram_is_init,
|
||||
alt_reset => core_alt_reset
|
||||
);
|
||||
|
||||
dram: entity work.litedram_wrapper
|
||||
generic map(
|
||||
DRAM_ABITS => 24,
|
||||
DRAM_ALINES => 1
|
||||
)
|
||||
port map(
|
||||
clk_in => clk,
|
||||
rst => rst,
|
||||
system_clk => system_clk,
|
||||
system_reset => soc_rst,
|
||||
core_alt_reset => core_alt_reset,
|
||||
pll_locked => open,
|
||||
|
||||
wb_in => wb_dram_in,
|
||||
wb_out => wb_dram_out,
|
||||
wb_ctrl_in => wb_dram_ctrl_in,
|
||||
wb_ctrl_out => wb_dram_ctrl_out,
|
||||
wb_ctrl_is_csr => wb_dram_is_csr,
|
||||
wb_ctrl_is_init => wb_dram_is_init,
|
||||
|
||||
serial_tx => open,
|
||||
serial_rx => '1',
|
||||
|
||||
init_done => open,
|
||||
init_error => open,
|
||||
|
||||
ddram_a => open,
|
||||
ddram_ba => open,
|
||||
ddram_ras_n => open,
|
||||
ddram_cas_n => open,
|
||||
ddram_we_n => open,
|
||||
ddram_cs_n => open,
|
||||
ddram_dm => open,
|
||||
ddram_dq => open,
|
||||
ddram_dqs_p => open,
|
||||
ddram_dqs_n => open,
|
||||
ddram_clk_p => open,
|
||||
ddram_clk_n => open,
|
||||
ddram_cke => open,
|
||||
ddram_odt => open,
|
||||
ddram_reset_n => open
|
||||
);
|
||||
|
||||
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;
|
||||
|
||||
end;
|
||||
@@ -21,14 +21,14 @@ class LiteDRAMGenerator(Generator):
|
||||
if os.path.exists(cpu_file):
|
||||
cpu = pathlib.Path(cpu_file).read_text()
|
||||
else:
|
||||
cpu = None
|
||||
cpu = "none"
|
||||
|
||||
print("CPU is ", cpu)
|
||||
|
||||
# Add files to fusesoc
|
||||
files = []
|
||||
f = os.path.join(gen_dir, "litedram_core.v")
|
||||
files.append({f : {'file_type' : 'verilogSource'}})
|
||||
f = os.path.join(gen_dir, "litedram-wrapper.vhdl")
|
||||
files.append({f : {'file_type' : 'vhdlSource-2008'}})
|
||||
f = os.path.join(gen_dir, "litedram-initmem.vhdl")
|
||||
files.append({f : {'file_type' : 'vhdlSource-2008'}})
|
||||
f = os.path.join(gen_dir, "litedram_core.init")
|
||||
@@ -36,8 +36,15 @@ class LiteDRAMGenerator(Generator):
|
||||
|
||||
# Look for init CPU types and add corresponding files
|
||||
if cpu == "vexriscv":
|
||||
f = os.path.join(base_dir, "extras", "VexRiscv.v")
|
||||
print("Adding VexRiscv files and wrapper")
|
||||
f = os.path.join(extras_dir, "VexRiscv.v")
|
||||
files.append({f : {'file_type' : 'verilogSource'}})
|
||||
f = os.path.join(extras_dir, "wrapper-self-init.vhdl")
|
||||
files.append({f : {'file_type' : 'vhdlSource-2008'}})
|
||||
else:
|
||||
print("Adding wrapper")
|
||||
f = os.path.join(extras_dir, "wrapper-mw-init.vhdl")
|
||||
files.append({f : {'file_type' : 'vhdlSource-2008'}})
|
||||
|
||||
self.add_files(files)
|
||||
|
||||
|
||||
10
litedram/extras/sim_dram_verilate.mk
Normal file
10
litedram/extras/sim_dram_verilate.mk
Normal file
@@ -0,0 +1,10 @@
|
||||
OPT_FAST=-O3 -fstrict-aliasing
|
||||
OPT_SLOW=-O3 -fstrict-aliasing
|
||||
|
||||
top_all: top_all2
|
||||
|
||||
include Vlitedram_core.mk
|
||||
|
||||
top_all2: default $(VK_GLOBAL_OBJS)
|
||||
|
||||
.PHONY: top_all top_all2
|
||||
214
litedram/extras/sim_litedram.vhdl
Normal file
214
litedram/extras/sim_litedram.vhdl
Normal file
@@ -0,0 +1,214 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package sim_litedram is
|
||||
-- WB req format:
|
||||
-- 73 .. 71 : cti(2..0)
|
||||
-- 70 .. 69 : bte(1..0)
|
||||
-- 68 .. 65 : sel(3..0)
|
||||
-- 64 : we
|
||||
-- 63 : stb
|
||||
-- 62 : cyc
|
||||
-- 61 .. 32 : addr(29..0)
|
||||
-- 31 .. 0 : write_data(31..0)
|
||||
--
|
||||
procedure litedram_set_wb(req : in std_ulogic_vector(73 downto 0));
|
||||
attribute foreign of litedram_set_wb : procedure is "VHPIDIRECT litedram_set_wb";
|
||||
|
||||
-- WB rsp format:
|
||||
-- 35 : init_error;
|
||||
-- 34 : init_done;
|
||||
-- 33 : err
|
||||
-- 32 : ack
|
||||
-- 31 .. 0 : read_data(31..0)
|
||||
--
|
||||
procedure litedram_get_wb(rsp : out std_ulogic_vector(35 downto 0));
|
||||
attribute foreign of litedram_get_wb : procedure is "VHPIDIRECT litedram_get_wb";
|
||||
|
||||
-- User req format:
|
||||
-- 171 : cmd_valid
|
||||
-- 170 : cmd_we
|
||||
-- 169 : wdata_valid
|
||||
-- 168 : rdata_ready
|
||||
-- 167 .. 144 : cmd_addr(23..0)
|
||||
-- 143 .. 128 : wdata_we(15..0)
|
||||
-- 127 .. 0 : wdata_data(127..0)
|
||||
--
|
||||
procedure litedram_set_user(req: in std_ulogic_vector(171 downto 0));
|
||||
attribute foreign of litedram_set_user : procedure is "VHPIDIRECT litedram_set_user";
|
||||
|
||||
-- User rsp format:
|
||||
-- 130 : cmd_ready
|
||||
-- 129 : wdata_ready
|
||||
-- 128 : rdata_valid
|
||||
-- 127 .. 0 : rdata_data(127..0)
|
||||
|
||||
procedure litedram_get_user(req: in std_ulogic_vector(130 downto 0));
|
||||
attribute foreign of litedram_get_user : procedure is "VHPIDIRECT litedram_get_user";
|
||||
|
||||
procedure litedram_clock;
|
||||
attribute foreign of litedram_clock : procedure is "VHPIDIRECT litedram_clock";
|
||||
|
||||
procedure litedram_init(trace: integer);
|
||||
attribute foreign of litedram_init : procedure is "VHPIDIRECT litedram_init";
|
||||
end sim_litedram;
|
||||
|
||||
package body sim_litedram is
|
||||
procedure litedram_set_wb(req : in std_ulogic_vector(73 downto 0)) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end procedure;
|
||||
procedure litedram_get_wb(rsp : out std_ulogic_vector(35 downto 0)) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end procedure;
|
||||
procedure litedram_set_user(req: in std_ulogic_vector(171 downto 0)) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end procedure;
|
||||
procedure litedram_get_user(req: in std_ulogic_vector(130 downto 0)) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end procedure;
|
||||
procedure litedram_clock is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end procedure;
|
||||
procedure litedram_init(trace: integer) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end procedure;
|
||||
end sim_litedram;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.sim_litedram.all;
|
||||
|
||||
entity litedram_core is
|
||||
port(
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
pll_locked : out std_ulogic;
|
||||
ddram_a : out std_ulogic_vector(0 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
ddram_ras_n : out std_ulogic;
|
||||
ddram_cas_n : out std_ulogic;
|
||||
ddram_we_n : out std_ulogic;
|
||||
ddram_cs_n : out std_ulogic;
|
||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_clk_p : out std_ulogic;
|
||||
ddram_clk_n : out std_ulogic;
|
||||
ddram_cke : out std_ulogic;
|
||||
ddram_odt : out std_ulogic;
|
||||
ddram_reset_n : out std_ulogic;
|
||||
init_done : out std_ulogic;
|
||||
init_error : out std_ulogic;
|
||||
user_clk : out std_ulogic;
|
||||
user_rst : out std_ulogic;
|
||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
||||
wb_ctrl_cyc : in std_ulogic;
|
||||
wb_ctrl_stb : in std_ulogic;
|
||||
wb_ctrl_ack : out std_ulogic;
|
||||
wb_ctrl_we : in std_ulogic;
|
||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
||||
wb_ctrl_err : out std_ulogic;
|
||||
user_port_native_0_cmd_valid : in std_ulogic;
|
||||
user_port_native_0_cmd_ready : out std_ulogic;
|
||||
user_port_native_0_cmd_we : in std_ulogic;
|
||||
user_port_native_0_cmd_addr : in std_ulogic_vector(23 downto 0);
|
||||
user_port_native_0_wdata_valid : in std_ulogic;
|
||||
user_port_native_0_wdata_ready : out std_ulogic;
|
||||
user_port_native_0_wdata_we : in std_ulogic_vector(15 downto 0);
|
||||
user_port_native_0_wdata_data : in std_ulogic_vector(127 downto 0);
|
||||
user_port_native_0_rdata_valid : out std_ulogic;
|
||||
user_port_native_0_rdata_ready : in std_ulogic;
|
||||
user_port_native_0_rdata_data : out std_ulogic_vector(127 downto 0)
|
||||
);
|
||||
end entity litedram_core;
|
||||
|
||||
architecture behaviour of litedram_core is
|
||||
signal idone : std_ulogic := '0';
|
||||
signal ierr : std_ulogic := '0';
|
||||
signal old_wb_cyc : std_ulogic := '1';
|
||||
begin
|
||||
user_rst <= rst;
|
||||
user_clk <= clk;
|
||||
pll_locked <= '1';
|
||||
init_done <= idone;
|
||||
init_error <= ierr;
|
||||
|
||||
poll: process(user_clk)
|
||||
procedure send_signals is
|
||||
begin
|
||||
litedram_set_wb(wb_ctrl_cti & wb_ctrl_bte &
|
||||
wb_ctrl_sel & wb_ctrl_we &
|
||||
wb_ctrl_stb & wb_ctrl_cyc &
|
||||
wb_ctrl_adr & wb_ctrl_dat_w);
|
||||
litedram_set_user(user_port_native_0_cmd_valid &
|
||||
user_port_native_0_cmd_we &
|
||||
user_port_native_0_wdata_valid &
|
||||
user_port_native_0_rdata_ready &
|
||||
user_port_native_0_cmd_addr &
|
||||
user_port_native_0_wdata_we &
|
||||
user_port_native_0_wdata_data);
|
||||
end procedure;
|
||||
|
||||
procedure recv_signals is
|
||||
variable wb_response : std_ulogic_vector(35 downto 0);
|
||||
variable ur_response : std_ulogic_vector(130 downto 0);
|
||||
begin
|
||||
litedram_get_wb(wb_response);
|
||||
wb_ctrl_dat_r <= wb_response(31 downto 0);
|
||||
wb_ctrl_ack <= wb_response(32);
|
||||
wb_ctrl_err <= wb_response(33);
|
||||
idone <= wb_response(34);
|
||||
ierr <= wb_response(35);
|
||||
litedram_get_user(ur_response);
|
||||
user_port_native_0_cmd_ready <= ur_response(130);
|
||||
user_port_native_0_wdata_ready <= ur_response(129);
|
||||
user_port_native_0_rdata_valid <= ur_response(128);
|
||||
user_port_native_0_rdata_data <= ur_response(127 downto 0);
|
||||
end procedure;
|
||||
|
||||
begin
|
||||
if rising_edge(user_clk) then
|
||||
|
||||
send_signals;
|
||||
recv_signals;
|
||||
-- Then generate a clock cycle ( 0->1 then 1->0 )
|
||||
litedram_clock;
|
||||
recv_signals;
|
||||
end if;
|
||||
|
||||
if falling_edge(user_clk) then
|
||||
send_signals;
|
||||
recv_signals;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
|
||||
library work;
|
||||
use work.sim_litedram.all;
|
||||
|
||||
entity litedram_trace_stub is
|
||||
end entity;
|
||||
|
||||
architecture behaviour of litedram_trace_stub is
|
||||
begin
|
||||
process
|
||||
begin
|
||||
litedram_init(1);
|
||||
wait;
|
||||
end process;
|
||||
end architecture;
|
||||
198
litedram/extras/sim_litedram_c.cpp
Normal file
198
litedram/extras/sim_litedram_c.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "sim_vhpi_c.h"
|
||||
#include "Vlitedram_core.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
|
||||
static Vlitedram_core *v;
|
||||
vluint64_t main_time = 0;
|
||||
|
||||
#if VM_TRACE
|
||||
VerilatedVcdC *tfp;
|
||||
#endif
|
||||
|
||||
static void cleanup(void)
|
||||
{
|
||||
#if VM_TRACE
|
||||
if (tfp) {
|
||||
tfp->flush();
|
||||
tfp->close();
|
||||
delete tfp;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void check_init(bool traces)
|
||||
{
|
||||
if (v)
|
||||
return;
|
||||
// XX Catch exceptions ?
|
||||
v = new Vlitedram_core;
|
||||
if (!v) {
|
||||
fprintf(stderr, "Failure allocating litedram core\n");
|
||||
exit(1);
|
||||
}
|
||||
#if VM_TRACE
|
||||
if (traces) {
|
||||
// init trace dump
|
||||
Verilated::traceEverOn(true);
|
||||
tfp = new VerilatedVcdC;
|
||||
v->trace(tfp, 99);
|
||||
tfp->open("litedram.vcd");
|
||||
}
|
||||
#endif
|
||||
atexit(cleanup);
|
||||
}
|
||||
|
||||
unsigned char get_bit(unsigned char **p)
|
||||
{
|
||||
unsigned char b = **p;
|
||||
|
||||
*p = *p + 1;
|
||||
|
||||
return b == vhpi1 ? 1 : 0;
|
||||
}
|
||||
|
||||
uint64_t get_bits(unsigned char **p, int len)
|
||||
{
|
||||
uint64_t r = 0;
|
||||
|
||||
while(len--)
|
||||
r = (r << 1) | get_bit(p);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void set_bit(unsigned char **p, int bit)
|
||||
{
|
||||
**p = bit ? vhpi1 : vhpi0;
|
||||
*p = *p + 1;
|
||||
}
|
||||
|
||||
void set_bits(unsigned char **p, uint64_t val, int len)
|
||||
{
|
||||
while(len--)
|
||||
set_bit(p, (val >> len) & 1);
|
||||
}
|
||||
|
||||
double sc_time_stamp(void)
|
||||
{
|
||||
return main_time;
|
||||
}
|
||||
|
||||
#define check_size(s, exp) \
|
||||
do { \
|
||||
int __s = (s); \
|
||||
int __e = (exp); \
|
||||
if (__s != __e) \
|
||||
fprintf(stderr, "WARNING: %s exp %d got %d\n", __func__, __e, __s); \
|
||||
} while(0)
|
||||
|
||||
static void do_eval(void)
|
||||
{
|
||||
v->eval();
|
||||
#if VM_TRACE
|
||||
if (tfp)
|
||||
tfp->dump((double) main_time);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void litedram_set_wb(unsigned char *req)
|
||||
{
|
||||
unsigned char *orig = req;
|
||||
|
||||
check_init(false);
|
||||
|
||||
v->wb_ctrl_cti = get_bits(&req, 3);
|
||||
v->wb_ctrl_bte = get_bits(&req, 2);
|
||||
v->wb_ctrl_sel = get_bits(&req, 4);
|
||||
v->wb_ctrl_we = get_bit(&req);
|
||||
v->wb_ctrl_stb = get_bit(&req);
|
||||
v->wb_ctrl_cyc = get_bit(&req);
|
||||
v->wb_ctrl_adr = get_bits(&req, 30);
|
||||
v->wb_ctrl_dat_w = get_bits(&req, 32);
|
||||
|
||||
check_size(req - orig, 74);
|
||||
|
||||
do_eval();
|
||||
}
|
||||
|
||||
extern "C" void litedram_get_wb(unsigned char *req)
|
||||
{
|
||||
unsigned char *orig = req;
|
||||
|
||||
check_init(false);
|
||||
|
||||
set_bit(&req, v->init_error);
|
||||
set_bit(&req, v->init_done);
|
||||
set_bit(&req, v->wb_ctrl_err);
|
||||
set_bit(&req, v->wb_ctrl_ack);
|
||||
set_bits(&req, v->wb_ctrl_dat_r, 32);
|
||||
|
||||
check_size(req - orig, 36);
|
||||
}
|
||||
|
||||
extern "C" void litedram_set_user(unsigned char *req)
|
||||
{
|
||||
unsigned char *orig = req;
|
||||
|
||||
check_init(false);
|
||||
|
||||
v->user_port_native_0_cmd_valid = get_bit(&req);
|
||||
v->user_port_native_0_cmd_we = get_bit(&req);
|
||||
v->user_port_native_0_wdata_valid = get_bit(&req);
|
||||
v->user_port_native_0_rdata_ready = get_bit(&req);
|
||||
v->user_port_native_0_cmd_addr = get_bits(&req, 24);
|
||||
v->user_port_native_0_wdata_we = get_bits(&req, 16);
|
||||
v->user_port_native_0_wdata_data[3] = get_bits(&req, 32);
|
||||
v->user_port_native_0_wdata_data[2] = get_bits(&req, 32);
|
||||
v->user_port_native_0_wdata_data[1] = get_bits(&req, 32);
|
||||
v->user_port_native_0_wdata_data[0] = get_bits(&req, 32);
|
||||
|
||||
check_size(req - orig, 172);
|
||||
|
||||
do_eval();
|
||||
}
|
||||
|
||||
extern "C" void litedram_get_user(unsigned char *req)
|
||||
{
|
||||
unsigned char *orig = req;
|
||||
|
||||
check_init(false);
|
||||
|
||||
set_bit(&req, v->user_port_native_0_cmd_ready);
|
||||
set_bit(&req, v->user_port_native_0_wdata_ready);
|
||||
set_bit(&req, v->user_port_native_0_rdata_valid);
|
||||
set_bits(&req, v->user_port_native_0_rdata_data[3], 32);
|
||||
set_bits(&req, v->user_port_native_0_rdata_data[2], 32);
|
||||
set_bits(&req, v->user_port_native_0_rdata_data[1], 32);
|
||||
set_bits(&req, v->user_port_native_0_rdata_data[0], 32);
|
||||
|
||||
check_size(req - orig, 131);
|
||||
}
|
||||
|
||||
extern "C" void litedram_clock(void)
|
||||
{
|
||||
check_init(false);
|
||||
|
||||
v->clk = 1;
|
||||
do_eval();
|
||||
main_time++;
|
||||
v->clk = 0;
|
||||
do_eval();
|
||||
main_time++;
|
||||
}
|
||||
|
||||
extern "C" void litedram_init(int trace_on)
|
||||
{
|
||||
check_init(!!trace_on);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,9 @@ use work.wishbone_types.all;
|
||||
entity litedram_wrapper is
|
||||
generic (
|
||||
DRAM_ABITS : positive;
|
||||
DRAM_ALINES : positive
|
||||
DRAM_ALINES : positive;
|
||||
-- Debug
|
||||
LITEDRAM_TRACE : boolean := false
|
||||
);
|
||||
port(
|
||||
-- LiteDRAM generates the system clock and reset
|
||||
@@ -233,6 +235,13 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
may_trace: if LITEDRAM_TRACE generate
|
||||
component litedram_trace_stub
|
||||
end component;
|
||||
begin
|
||||
litedram_trace: litedram_trace_stub;
|
||||
end generate;
|
||||
|
||||
litedram: litedram_core
|
||||
port map(
|
||||
clk => clk_in,
|
||||
@@ -22,7 +22,7 @@ def make_new_dir(base, added):
|
||||
return r
|
||||
|
||||
gen_src_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
base_dir = os.path.join(gen_src_dir, os.pardir)
|
||||
base_dir = os.path.normpath(os.path.join(gen_src_dir, os.pardir))
|
||||
build_top_dir = make_new_dir(base_dir, "build")
|
||||
gen_src_dir = os.path.join(base_dir, "gen-src")
|
||||
gen_dir = make_new_dir(base_dir, "generated")
|
||||
@@ -31,7 +31,7 @@ gen_dir = make_new_dir(base_dir, "generated")
|
||||
#
|
||||
# XXX Not working yet
|
||||
#
|
||||
def build_init_code(build_dir):
|
||||
def build_init_code(build_dir, is_sim):
|
||||
|
||||
# More path fudging
|
||||
sw_dir = os.path.join(build_dir, "software");
|
||||
@@ -62,6 +62,8 @@ def build_init_code(build_dir):
|
||||
add_var("GENINC_DIR", sw_inc_dir)
|
||||
add_var("LXSRC_DIR", lxbios_src_dir)
|
||||
add_var("LXINC_DIR", lxbios_inc_dir)
|
||||
if is_sim:
|
||||
add_var("EXTRA_CFLAGS", "-D__SIM__")
|
||||
write_to_file(os.path.join(gen_inc_dir, "variables.mak"), "".join(env_vars))
|
||||
|
||||
# Build init code
|
||||
@@ -76,6 +78,9 @@ def generate_one(t, mw_init):
|
||||
|
||||
print("Generating target:", t)
|
||||
|
||||
# Is it a simulation ?
|
||||
is_sim = t is "sim"
|
||||
|
||||
# Muck with directory path
|
||||
build_dir = make_new_dir(build_top_dir, t)
|
||||
t_dir = make_new_dir(gen_dir, t)
|
||||
@@ -107,14 +112,16 @@ def generate_one(t, mw_init):
|
||||
core_config["csr_alignment"] = 64
|
||||
|
||||
# Generate core
|
||||
if core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
||||
if is_sim:
|
||||
platform = SimPlatform("", io=[])
|
||||
elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
||||
platform = LatticePlatform("LFE5UM5G-45F-8BG381C", io=[], toolchain="trellis")
|
||||
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
||||
platform = XilinxPlatform("", io=[], toolchain="vivado")
|
||||
else:
|
||||
raise ValueError("Unsupported SDRAM PHY: {}".format(core_config["sdram_phy"]))
|
||||
|
||||
soc = LiteDRAMCore(platform, core_config, integrated_rom_size=0x6000, csr_data_width=32)
|
||||
soc = LiteDRAMCore(platform, core_config, is_sim = is_sim, integrated_rom_size=0x6000, csr_data_width=32)
|
||||
|
||||
# Build into build_dir
|
||||
builder = Builder(soc, output_dir=build_dir, compile_gateware=False)
|
||||
@@ -123,32 +130,35 @@ def generate_one(t, mw_init):
|
||||
# Grab generated gatewar dir
|
||||
gw_dir = os.path.join(build_dir, "gateware")
|
||||
|
||||
# Generate init-cpu.txt if any and generate init code if none
|
||||
# Generate init-cpu.txt and generate init code
|
||||
cpu = core_config["cpu"]
|
||||
if mw_init:
|
||||
src_wrap_file = os.path.join(gen_src_dir, "wrapper-mw-init.vhdl")
|
||||
src_init_file = build_init_code(build_dir)
|
||||
write_to_file(os.path.join(t_dir, "init-cpu.txt"), "none")
|
||||
src_init_file = build_init_code(build_dir, is_sim)
|
||||
src_initram_file = os.path.join(gen_src_dir, "dram-init-mem.vhdl")
|
||||
else:
|
||||
write_to_file(os.path.join(t_dir, "init-cpu.txt"), cpu)
|
||||
src_wrap_file = os.path.join(gen_src_dir, "wrapper-self-init.vhdl")
|
||||
src_init_file = os.path.join(gw_dir, "mem.init")
|
||||
src_initram_file = os.path.join(gen_src_dir, "no-init-mem.vhdl")
|
||||
|
||||
# Copy generated files to target dir, amend them if necessary
|
||||
initfile_name = "litedram_core.init"
|
||||
core_file = os.path.join(gw_dir, "litedram_core.v")
|
||||
dst_init_file = os.path.join(t_dir, "litedram_core.init")
|
||||
dst_wrap_file = os.path.join(t_dir, "litedram-wrapper.vhdl")
|
||||
dst_init_file = os.path.join(t_dir, initfile_name)
|
||||
dst_initram_file = os.path.join(t_dir, "litedram-initmem.vhdl")
|
||||
replace_in_file(core_file, "mem.init", "litedram_core.init")
|
||||
shutil.copy(core_file, t_dir)
|
||||
if not mw_init:
|
||||
replace_in_file(core_file, "mem.init", initfile_name)
|
||||
shutil.copyfile(src_init_file, dst_init_file)
|
||||
shutil.copyfile(src_wrap_file, dst_wrap_file)
|
||||
shutil.copyfile(src_initram_file, dst_initram_file)
|
||||
if is_sim:
|
||||
initfile_path = os.path.join("litedram", "generated", "sim", initfile_name)
|
||||
replace_in_file(dst_initram_file, initfile_name, initfile_path)
|
||||
shutil.copy(core_file, t_dir)
|
||||
|
||||
def main():
|
||||
|
||||
targets = ['arty','nexys-video']
|
||||
targets = ['arty','nexys-video', 'sim']
|
||||
# targets = ['sim']
|
||||
|
||||
# XXX Set mw_init to False to use a local VexRiscV for memory inits
|
||||
for t in targets:
|
||||
|
||||
@@ -21,7 +21,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
|
||||
#### Flags
|
||||
|
||||
CPPFLAGS = -nostdinc -D__USE_LIBC
|
||||
CPPFLAGS = -nostdinc -D__USE_LIBC $(EXTRA_CFLAGS)
|
||||
CPPFLAGS += -I$(SRC_DIR)/libc/include -I$(LXSRC_DIR) -I$(LXINC_DIR) -I$(GENINC_DIR) -I$(SRC_DIR)/include -I$(SRC_DIR)/../../../include
|
||||
CPPFLAGS += -isystem $(shell $(CC) -print-file-name=include)
|
||||
CFLAGS = -Os -g -Wall -std=c99 -m64 -mabi=elfv2 -msoft-float -mno-string -mno-multiple -mno-vsx -mno-altivec -mlittle-endian -fno-stack-protector -mstrict-align -ffreestanding -fdata-sections -ffunction-sections -fno-delete-null-pointer-checks
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#define CSR_BASE DRAM_CTRL_BASE
|
||||
#define CONFIG_CPU_NOP "nop"
|
||||
|
||||
#ifdef __SIM__
|
||||
#define MEMTEST_BUS_SIZE 16
|
||||
#define MEMTEST_DATA_SIZE 16
|
||||
#define MEMTEST_ADDR_SIZE 16
|
||||
#define CONFIG_SIM_DISABLE_DELAYS
|
||||
#endif
|
||||
|
||||
extern void flush_cpu_dcache(void);
|
||||
extern void flush_cpu_icache(void);
|
||||
static inline void flush_l2_cache(void) { }
|
||||
|
||||
39
litedram/gen-src/sim.yml
Normal file
39
litedram/gen-src/sim.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
{
|
||||
# General ------------------------------------------------------------------
|
||||
"cpu": "None", # Type of CPU used for init/calib (vexriscv, lm32)
|
||||
"cpu_variant":"minimal",
|
||||
"speedgrade": -1, # FPGA speedgrade
|
||||
"memtype": "DDR3", # DRAM type
|
||||
"sim" : "True",
|
||||
|
||||
# PHY ----------------------------------------------------------------------
|
||||
"cmd_delay": 0, # Command additional delay (in taps)
|
||||
"cmd_latency": 0, # Command additional latency
|
||||
"sdram_module": "MT41K128M16", # SDRAM modules of the board or SO-DIMM
|
||||
"sdram_module_nb": 2, # Number of byte groups
|
||||
"sdram_rank_nb": 1, # Number of ranks
|
||||
"sdram_phy": "A7DDRPHY", # Type of FPGA PHY
|
||||
|
||||
# Electrical ---------------------------------------------------------------
|
||||
"rtt_nom": "60ohm", # Nominal termination
|
||||
"rtt_wr": "60ohm", # Write termination
|
||||
"ron": "34ohm", # Output driver impedance
|
||||
|
||||
# Frequency ----------------------------------------------------------------
|
||||
"input_clk_freq": 100e6, # Input clock frequency
|
||||
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
||||
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
||||
|
||||
# Core ---------------------------------------------------------------------
|
||||
"cmd_buffer_depth": 16, # Depth of the command buffer
|
||||
|
||||
# User Ports ---------------------------------------------------------------
|
||||
"user_ports": {
|
||||
"native_0": {
|
||||
"type": "native",
|
||||
},
|
||||
},
|
||||
}
|
||||
1
litedram/generated/arty/init-cpu.txt
Normal file
1
litedram/generated/arty/init-cpu.txt
Normal file
@@ -0,0 +1 @@
|
||||
none
|
||||
@@ -1,284 +0,0 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity litedram_wrapper is
|
||||
generic (
|
||||
DRAM_ABITS : positive;
|
||||
DRAM_ALINES : positive
|
||||
);
|
||||
port(
|
||||
-- LiteDRAM generates the system clock and reset
|
||||
-- from the input clkin
|
||||
clk_in : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
system_clk : out std_ulogic;
|
||||
system_reset : out std_ulogic;
|
||||
core_alt_reset : out std_ulogic;
|
||||
pll_locked : out std_ulogic;
|
||||
|
||||
-- Wishbone ports:
|
||||
wb_in : in wishbone_master_out;
|
||||
wb_out : out wishbone_slave_out;
|
||||
wb_ctrl_in : in wb_io_master_out;
|
||||
wb_ctrl_out : out wb_io_slave_out;
|
||||
wb_ctrl_is_csr : in std_ulogic;
|
||||
wb_ctrl_is_init : in std_ulogic;
|
||||
|
||||
-- Init core serial debug
|
||||
serial_tx : out std_ulogic;
|
||||
serial_rx : in std_ulogic;
|
||||
|
||||
-- Misc
|
||||
init_done : out std_ulogic;
|
||||
init_error : out std_ulogic;
|
||||
|
||||
-- DRAM wires
|
||||
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
ddram_ras_n : out std_ulogic;
|
||||
ddram_cas_n : out std_ulogic;
|
||||
ddram_we_n : out std_ulogic;
|
||||
ddram_cs_n : out std_ulogic;
|
||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_clk_p : out std_ulogic;
|
||||
ddram_clk_n : out std_ulogic;
|
||||
ddram_cke : out std_ulogic;
|
||||
ddram_odt : out std_ulogic;
|
||||
ddram_reset_n : out std_ulogic
|
||||
);
|
||||
end entity litedram_wrapper;
|
||||
|
||||
architecture behaviour of litedram_wrapper is
|
||||
|
||||
component litedram_core port (
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
pll_locked : out std_ulogic;
|
||||
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
ddram_ras_n : out std_ulogic;
|
||||
ddram_cas_n : out std_ulogic;
|
||||
ddram_we_n : out std_ulogic;
|
||||
ddram_cs_n : out std_ulogic;
|
||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_clk_p : out std_ulogic;
|
||||
ddram_clk_n : out std_ulogic;
|
||||
ddram_cke : out std_ulogic;
|
||||
ddram_odt : out std_ulogic;
|
||||
ddram_reset_n : out std_ulogic;
|
||||
init_done : out std_ulogic;
|
||||
init_error : out std_ulogic;
|
||||
user_clk : out std_ulogic;
|
||||
user_rst : out std_ulogic;
|
||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
||||
wb_ctrl_cyc : in std_ulogic;
|
||||
wb_ctrl_stb : in std_ulogic;
|
||||
wb_ctrl_ack : out std_ulogic;
|
||||
wb_ctrl_we : in std_ulogic;
|
||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
||||
wb_ctrl_err : out std_ulogic;
|
||||
user_port_native_0_cmd_valid : in std_ulogic;
|
||||
user_port_native_0_cmd_ready : out std_ulogic;
|
||||
user_port_native_0_cmd_we : in std_ulogic;
|
||||
user_port_native_0_cmd_addr : in std_ulogic_vector(DRAM_ABITS-1 downto 0);
|
||||
user_port_native_0_wdata_valid : in std_ulogic;
|
||||
user_port_native_0_wdata_ready : out std_ulogic;
|
||||
user_port_native_0_wdata_we : in std_ulogic_vector(15 downto 0);
|
||||
user_port_native_0_wdata_data : in std_ulogic_vector(127 downto 0);
|
||||
user_port_native_0_rdata_valid : out std_ulogic;
|
||||
user_port_native_0_rdata_ready : in std_ulogic;
|
||||
user_port_native_0_rdata_data : out std_ulogic_vector(127 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal user_port0_cmd_valid : std_ulogic;
|
||||
signal user_port0_cmd_ready : std_ulogic;
|
||||
signal user_port0_cmd_we : std_ulogic;
|
||||
signal user_port0_cmd_addr : std_ulogic_vector(DRAM_ABITS-1 downto 0);
|
||||
signal user_port0_wdata_valid : std_ulogic;
|
||||
signal user_port0_wdata_ready : std_ulogic;
|
||||
signal user_port0_wdata_we : std_ulogic_vector(15 downto 0);
|
||||
signal user_port0_wdata_data : std_ulogic_vector(127 downto 0);
|
||||
signal user_port0_rdata_valid : std_ulogic;
|
||||
signal user_port0_rdata_ready : std_ulogic;
|
||||
signal user_port0_rdata_data : std_ulogic_vector(127 downto 0);
|
||||
|
||||
signal ad3 : std_ulogic;
|
||||
|
||||
signal wb_ctrl_adr : std_ulogic_vector(29 downto 0);
|
||||
signal wb_ctrl_dat_w : std_ulogic_vector(31 downto 0);
|
||||
signal wb_ctrl_dat_r : std_ulogic_vector(31 downto 0);
|
||||
signal wb_ctrl_sel : std_ulogic_vector(3 downto 0);
|
||||
signal wb_ctrl_cyc : std_ulogic;
|
||||
signal wb_ctrl_stb : std_ulogic;
|
||||
signal wb_ctrl_ack : std_ulogic;
|
||||
signal wb_ctrl_we : std_ulogic;
|
||||
|
||||
signal wb_init_in : wb_io_master_out;
|
||||
signal wb_init_out : wb_io_slave_out;
|
||||
|
||||
type state_t is (CMD, MWRITE, MREAD);
|
||||
signal state : state_t;
|
||||
|
||||
begin
|
||||
|
||||
-- alternate core reset address set when DRAM is not initialized.
|
||||
core_alt_reset <= not init_done;
|
||||
|
||||
-- Init code BRAM memory slave
|
||||
init_ram_0: entity work.dram_init_mem
|
||||
port map(
|
||||
clk => system_clk,
|
||||
wb_in => wb_init_in,
|
||||
wb_out => wb_init_out
|
||||
);
|
||||
|
||||
--
|
||||
-- Control bus wishbone: This muxes the wishbone to the CSRs
|
||||
-- and an internal small one to the init BRAM
|
||||
--
|
||||
|
||||
-- Init DRAM wishbone IN signals
|
||||
wb_init_in.adr <= wb_ctrl_in.adr;
|
||||
wb_init_in.dat <= wb_ctrl_in.dat;
|
||||
wb_init_in.sel <= wb_ctrl_in.sel;
|
||||
wb_init_in.we <= wb_ctrl_in.we;
|
||||
wb_init_in.stb <= wb_ctrl_in.stb;
|
||||
wb_init_in.cyc <= wb_ctrl_in.cyc and wb_ctrl_is_init;
|
||||
|
||||
-- DRAM CSR IN signals
|
||||
wb_ctrl_adr <= x"0000" & wb_ctrl_in.adr(15 downto 2);
|
||||
wb_ctrl_dat_w <= wb_ctrl_in.dat;
|
||||
wb_ctrl_sel <= wb_ctrl_in.sel;
|
||||
wb_ctrl_we <= wb_ctrl_in.we;
|
||||
wb_ctrl_cyc <= wb_ctrl_in.cyc and wb_ctrl_is_csr;
|
||||
wb_ctrl_stb <= wb_ctrl_in.stb and wb_ctrl_is_csr;
|
||||
|
||||
-- Ctrl bus wishbone OUT signals
|
||||
wb_ctrl_out.ack <= wb_ctrl_ack when wb_ctrl_is_csr = '1'
|
||||
else wb_init_out.ack;
|
||||
wb_ctrl_out.dat <= wb_ctrl_dat_r when wb_ctrl_is_csr = '1'
|
||||
else wb_init_out.dat;
|
||||
wb_ctrl_out.stall <= wb_init_out.stall when wb_ctrl_is_init else
|
||||
'0' when wb_ctrl_in.cyc = '0' else not wb_ctrl_ack;
|
||||
|
||||
--
|
||||
-- Data bus wishbone to LiteDRAM native port
|
||||
--
|
||||
-- Address bit 3 selects the top or bottom half of the data
|
||||
-- bus (64-bit wishbone vs. 128-bit DRAM interface)
|
||||
--
|
||||
-- XXX TODO: Figure out how to pipeline this
|
||||
--
|
||||
ad3 <= wb_in.adr(3);
|
||||
|
||||
-- Wishbone port IN signals
|
||||
user_port0_cmd_valid <= wb_in.cyc and wb_in.stb when state = CMD else '0';
|
||||
user_port0_cmd_we <= wb_in.we when state = CMD else '0';
|
||||
user_port0_wdata_valid <= '1' when state = MWRITE else '0';
|
||||
user_port0_rdata_ready <= '1' when state = MREAD else '0';
|
||||
user_port0_cmd_addr <= wb_in.adr(DRAM_ABITS+3 downto 4);
|
||||
user_port0_wdata_data <= wb_in.dat & wb_in.dat;
|
||||
user_port0_wdata_we <= wb_in.sel & "00000000" when ad3 = '1' else
|
||||
"00000000" & wb_in.sel;
|
||||
|
||||
-- Wishbone OUT signals
|
||||
wb_out.ack <= user_port0_wdata_ready when state = MWRITE else
|
||||
user_port0_rdata_valid when state = MREAD else '0';
|
||||
|
||||
wb_out.dat <= user_port0_rdata_data(127 downto 64) when ad3 = '1' else
|
||||
user_port0_rdata_data(63 downto 0);
|
||||
|
||||
-- We don't do pipelining yet.
|
||||
wb_out.stall <= '0' when wb_in.cyc = '0' else not wb_out.ack;
|
||||
|
||||
-- DRAM user port State machine
|
||||
sm: process(system_clk)
|
||||
begin
|
||||
|
||||
if rising_edge(system_clk) then
|
||||
if system_reset = '1' then
|
||||
state <= CMD;
|
||||
else
|
||||
case state is
|
||||
when CMD =>
|
||||
if (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
|
||||
state <= MWRITE when wb_in.we = '1' else MREAD;
|
||||
end if;
|
||||
when MWRITE =>
|
||||
if user_port0_wdata_ready = '1' then
|
||||
state <= CMD;
|
||||
end if;
|
||||
when MREAD =>
|
||||
if user_port0_rdata_valid = '1' then
|
||||
state <= CMD;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
litedram: litedram_core
|
||||
port map(
|
||||
clk => clk_in,
|
||||
rst => rst,
|
||||
pll_locked => pll_locked,
|
||||
ddram_a => ddram_a,
|
||||
ddram_ba => ddram_ba,
|
||||
ddram_ras_n => ddram_ras_n,
|
||||
ddram_cas_n => ddram_cas_n,
|
||||
ddram_we_n => ddram_we_n,
|
||||
ddram_cs_n => ddram_cs_n,
|
||||
ddram_dm => ddram_dm,
|
||||
ddram_dq => ddram_dq,
|
||||
ddram_dqs_p => ddram_dqs_p,
|
||||
ddram_dqs_n => ddram_dqs_n,
|
||||
ddram_clk_p => ddram_clk_p,
|
||||
ddram_clk_n => ddram_clk_n,
|
||||
ddram_cke => ddram_cke,
|
||||
ddram_odt => ddram_odt,
|
||||
ddram_reset_n => ddram_reset_n,
|
||||
init_done => init_done,
|
||||
init_error => init_error,
|
||||
user_clk => system_clk,
|
||||
user_rst => system_reset,
|
||||
wb_ctrl_adr => wb_ctrl_adr,
|
||||
wb_ctrl_dat_w => wb_ctrl_dat_w,
|
||||
wb_ctrl_dat_r => wb_ctrl_dat_r,
|
||||
wb_ctrl_sel => wb_ctrl_sel,
|
||||
wb_ctrl_cyc => wb_ctrl_cyc,
|
||||
wb_ctrl_stb => wb_ctrl_stb,
|
||||
wb_ctrl_ack => wb_ctrl_ack,
|
||||
wb_ctrl_we => wb_ctrl_we,
|
||||
wb_ctrl_cti => "000",
|
||||
wb_ctrl_bte => "00",
|
||||
wb_ctrl_err => open,
|
||||
user_port_native_0_cmd_valid => user_port0_cmd_valid,
|
||||
user_port_native_0_cmd_ready => user_port0_cmd_ready,
|
||||
user_port_native_0_cmd_we => user_port0_cmd_we,
|
||||
user_port_native_0_cmd_addr => user_port0_cmd_addr,
|
||||
user_port_native_0_wdata_valid => user_port0_wdata_valid,
|
||||
user_port_native_0_wdata_ready => user_port0_wdata_ready,
|
||||
user_port_native_0_wdata_we => user_port0_wdata_we,
|
||||
user_port_native_0_wdata_data => user_port0_wdata_data,
|
||||
user_port_native_0_rdata_valid => user_port0_rdata_valid,
|
||||
user_port_native_0_rdata_ready => user_port0_rdata_ready,
|
||||
user_port_native_0_rdata_data => user_port0_rdata_data
|
||||
);
|
||||
|
||||
end architecture behaviour;
|
||||
@@ -1443,7 +1443,7 @@ e8010010ebc1fff0
|
||||
203a4b4c43202020
|
||||
7a484d20646c6c25
|
||||
000000000000000a
|
||||
6138393331393333
|
||||
6131333764343635
|
||||
0000000000000000
|
||||
0033306536316430
|
||||
4d4152446574694c
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//--------------------------------------------------------------------------------
|
||||
// Auto-generated by Migen (0d16e03) & LiteX (3391398a) on 2020-05-21 19:21:27
|
||||
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-22 17:57:16
|
||||
//--------------------------------------------------------------------------------
|
||||
module litedram_core(
|
||||
input wire clk,
|
||||
|
||||
1
litedram/generated/nexys-video/init-cpu.txt
Normal file
1
litedram/generated/nexys-video/init-cpu.txt
Normal file
@@ -0,0 +1 @@
|
||||
none
|
||||
@@ -1,284 +0,0 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity litedram_wrapper is
|
||||
generic (
|
||||
DRAM_ABITS : positive;
|
||||
DRAM_ALINES : positive
|
||||
);
|
||||
port(
|
||||
-- LiteDRAM generates the system clock and reset
|
||||
-- from the input clkin
|
||||
clk_in : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
system_clk : out std_ulogic;
|
||||
system_reset : out std_ulogic;
|
||||
core_alt_reset : out std_ulogic;
|
||||
pll_locked : out std_ulogic;
|
||||
|
||||
-- Wishbone ports:
|
||||
wb_in : in wishbone_master_out;
|
||||
wb_out : out wishbone_slave_out;
|
||||
wb_ctrl_in : in wb_io_master_out;
|
||||
wb_ctrl_out : out wb_io_slave_out;
|
||||
wb_ctrl_is_csr : in std_ulogic;
|
||||
wb_ctrl_is_init : in std_ulogic;
|
||||
|
||||
-- Init core serial debug
|
||||
serial_tx : out std_ulogic;
|
||||
serial_rx : in std_ulogic;
|
||||
|
||||
-- Misc
|
||||
init_done : out std_ulogic;
|
||||
init_error : out std_ulogic;
|
||||
|
||||
-- DRAM wires
|
||||
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
ddram_ras_n : out std_ulogic;
|
||||
ddram_cas_n : out std_ulogic;
|
||||
ddram_we_n : out std_ulogic;
|
||||
ddram_cs_n : out std_ulogic;
|
||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_clk_p : out std_ulogic;
|
||||
ddram_clk_n : out std_ulogic;
|
||||
ddram_cke : out std_ulogic;
|
||||
ddram_odt : out std_ulogic;
|
||||
ddram_reset_n : out std_ulogic
|
||||
);
|
||||
end entity litedram_wrapper;
|
||||
|
||||
architecture behaviour of litedram_wrapper is
|
||||
|
||||
component litedram_core port (
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
pll_locked : out std_ulogic;
|
||||
ddram_a : out std_ulogic_vector(DRAM_ALINES-1 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
ddram_ras_n : out std_ulogic;
|
||||
ddram_cas_n : out std_ulogic;
|
||||
ddram_we_n : out std_ulogic;
|
||||
ddram_cs_n : out std_ulogic;
|
||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
||||
ddram_clk_p : out std_ulogic;
|
||||
ddram_clk_n : out std_ulogic;
|
||||
ddram_cke : out std_ulogic;
|
||||
ddram_odt : out std_ulogic;
|
||||
ddram_reset_n : out std_ulogic;
|
||||
init_done : out std_ulogic;
|
||||
init_error : out std_ulogic;
|
||||
user_clk : out std_ulogic;
|
||||
user_rst : out std_ulogic;
|
||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
||||
wb_ctrl_cyc : in std_ulogic;
|
||||
wb_ctrl_stb : in std_ulogic;
|
||||
wb_ctrl_ack : out std_ulogic;
|
||||
wb_ctrl_we : in std_ulogic;
|
||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
||||
wb_ctrl_err : out std_ulogic;
|
||||
user_port_native_0_cmd_valid : in std_ulogic;
|
||||
user_port_native_0_cmd_ready : out std_ulogic;
|
||||
user_port_native_0_cmd_we : in std_ulogic;
|
||||
user_port_native_0_cmd_addr : in std_ulogic_vector(DRAM_ABITS-1 downto 0);
|
||||
user_port_native_0_wdata_valid : in std_ulogic;
|
||||
user_port_native_0_wdata_ready : out std_ulogic;
|
||||
user_port_native_0_wdata_we : in std_ulogic_vector(15 downto 0);
|
||||
user_port_native_0_wdata_data : in std_ulogic_vector(127 downto 0);
|
||||
user_port_native_0_rdata_valid : out std_ulogic;
|
||||
user_port_native_0_rdata_ready : in std_ulogic;
|
||||
user_port_native_0_rdata_data : out std_ulogic_vector(127 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal user_port0_cmd_valid : std_ulogic;
|
||||
signal user_port0_cmd_ready : std_ulogic;
|
||||
signal user_port0_cmd_we : std_ulogic;
|
||||
signal user_port0_cmd_addr : std_ulogic_vector(DRAM_ABITS-1 downto 0);
|
||||
signal user_port0_wdata_valid : std_ulogic;
|
||||
signal user_port0_wdata_ready : std_ulogic;
|
||||
signal user_port0_wdata_we : std_ulogic_vector(15 downto 0);
|
||||
signal user_port0_wdata_data : std_ulogic_vector(127 downto 0);
|
||||
signal user_port0_rdata_valid : std_ulogic;
|
||||
signal user_port0_rdata_ready : std_ulogic;
|
||||
signal user_port0_rdata_data : std_ulogic_vector(127 downto 0);
|
||||
|
||||
signal ad3 : std_ulogic;
|
||||
|
||||
signal wb_ctrl_adr : std_ulogic_vector(29 downto 0);
|
||||
signal wb_ctrl_dat_w : std_ulogic_vector(31 downto 0);
|
||||
signal wb_ctrl_dat_r : std_ulogic_vector(31 downto 0);
|
||||
signal wb_ctrl_sel : std_ulogic_vector(3 downto 0);
|
||||
signal wb_ctrl_cyc : std_ulogic;
|
||||
signal wb_ctrl_stb : std_ulogic;
|
||||
signal wb_ctrl_ack : std_ulogic;
|
||||
signal wb_ctrl_we : std_ulogic;
|
||||
|
||||
signal wb_init_in : wb_io_master_out;
|
||||
signal wb_init_out : wb_io_slave_out;
|
||||
|
||||
type state_t is (CMD, MWRITE, MREAD);
|
||||
signal state : state_t;
|
||||
|
||||
begin
|
||||
|
||||
-- alternate core reset address set when DRAM is not initialized.
|
||||
core_alt_reset <= not init_done;
|
||||
|
||||
-- Init code BRAM memory slave
|
||||
init_ram_0: entity work.dram_init_mem
|
||||
port map(
|
||||
clk => system_clk,
|
||||
wb_in => wb_init_in,
|
||||
wb_out => wb_init_out
|
||||
);
|
||||
|
||||
--
|
||||
-- Control bus wishbone: This muxes the wishbone to the CSRs
|
||||
-- and an internal small one to the init BRAM
|
||||
--
|
||||
|
||||
-- Init DRAM wishbone IN signals
|
||||
wb_init_in.adr <= wb_ctrl_in.adr;
|
||||
wb_init_in.dat <= wb_ctrl_in.dat;
|
||||
wb_init_in.sel <= wb_ctrl_in.sel;
|
||||
wb_init_in.we <= wb_ctrl_in.we;
|
||||
wb_init_in.stb <= wb_ctrl_in.stb;
|
||||
wb_init_in.cyc <= wb_ctrl_in.cyc and wb_ctrl_is_init;
|
||||
|
||||
-- DRAM CSR IN signals
|
||||
wb_ctrl_adr <= x"0000" & wb_ctrl_in.adr(15 downto 2);
|
||||
wb_ctrl_dat_w <= wb_ctrl_in.dat;
|
||||
wb_ctrl_sel <= wb_ctrl_in.sel;
|
||||
wb_ctrl_we <= wb_ctrl_in.we;
|
||||
wb_ctrl_cyc <= wb_ctrl_in.cyc and wb_ctrl_is_csr;
|
||||
wb_ctrl_stb <= wb_ctrl_in.stb and wb_ctrl_is_csr;
|
||||
|
||||
-- Ctrl bus wishbone OUT signals
|
||||
wb_ctrl_out.ack <= wb_ctrl_ack when wb_ctrl_is_csr = '1'
|
||||
else wb_init_out.ack;
|
||||
wb_ctrl_out.dat <= wb_ctrl_dat_r when wb_ctrl_is_csr = '1'
|
||||
else wb_init_out.dat;
|
||||
wb_ctrl_out.stall <= wb_init_out.stall when wb_ctrl_is_init else
|
||||
'0' when wb_ctrl_in.cyc = '0' else not wb_ctrl_ack;
|
||||
|
||||
--
|
||||
-- Data bus wishbone to LiteDRAM native port
|
||||
--
|
||||
-- Address bit 3 selects the top or bottom half of the data
|
||||
-- bus (64-bit wishbone vs. 128-bit DRAM interface)
|
||||
--
|
||||
-- XXX TODO: Figure out how to pipeline this
|
||||
--
|
||||
ad3 <= wb_in.adr(3);
|
||||
|
||||
-- Wishbone port IN signals
|
||||
user_port0_cmd_valid <= wb_in.cyc and wb_in.stb when state = CMD else '0';
|
||||
user_port0_cmd_we <= wb_in.we when state = CMD else '0';
|
||||
user_port0_wdata_valid <= '1' when state = MWRITE else '0';
|
||||
user_port0_rdata_ready <= '1' when state = MREAD else '0';
|
||||
user_port0_cmd_addr <= wb_in.adr(DRAM_ABITS+3 downto 4);
|
||||
user_port0_wdata_data <= wb_in.dat & wb_in.dat;
|
||||
user_port0_wdata_we <= wb_in.sel & "00000000" when ad3 = '1' else
|
||||
"00000000" & wb_in.sel;
|
||||
|
||||
-- Wishbone OUT signals
|
||||
wb_out.ack <= user_port0_wdata_ready when state = MWRITE else
|
||||
user_port0_rdata_valid when state = MREAD else '0';
|
||||
|
||||
wb_out.dat <= user_port0_rdata_data(127 downto 64) when ad3 = '1' else
|
||||
user_port0_rdata_data(63 downto 0);
|
||||
|
||||
-- We don't do pipelining yet.
|
||||
wb_out.stall <= '0' when wb_in.cyc = '0' else not wb_out.ack;
|
||||
|
||||
-- DRAM user port State machine
|
||||
sm: process(system_clk)
|
||||
begin
|
||||
|
||||
if rising_edge(system_clk) then
|
||||
if system_reset = '1' then
|
||||
state <= CMD;
|
||||
else
|
||||
case state is
|
||||
when CMD =>
|
||||
if (user_port0_cmd_ready and user_port0_cmd_valid) = '1' then
|
||||
state <= MWRITE when wb_in.we = '1' else MREAD;
|
||||
end if;
|
||||
when MWRITE =>
|
||||
if user_port0_wdata_ready = '1' then
|
||||
state <= CMD;
|
||||
end if;
|
||||
when MREAD =>
|
||||
if user_port0_rdata_valid = '1' then
|
||||
state <= CMD;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
litedram: litedram_core
|
||||
port map(
|
||||
clk => clk_in,
|
||||
rst => rst,
|
||||
pll_locked => pll_locked,
|
||||
ddram_a => ddram_a,
|
||||
ddram_ba => ddram_ba,
|
||||
ddram_ras_n => ddram_ras_n,
|
||||
ddram_cas_n => ddram_cas_n,
|
||||
ddram_we_n => ddram_we_n,
|
||||
ddram_cs_n => ddram_cs_n,
|
||||
ddram_dm => ddram_dm,
|
||||
ddram_dq => ddram_dq,
|
||||
ddram_dqs_p => ddram_dqs_p,
|
||||
ddram_dqs_n => ddram_dqs_n,
|
||||
ddram_clk_p => ddram_clk_p,
|
||||
ddram_clk_n => ddram_clk_n,
|
||||
ddram_cke => ddram_cke,
|
||||
ddram_odt => ddram_odt,
|
||||
ddram_reset_n => ddram_reset_n,
|
||||
init_done => init_done,
|
||||
init_error => init_error,
|
||||
user_clk => system_clk,
|
||||
user_rst => system_reset,
|
||||
wb_ctrl_adr => wb_ctrl_adr,
|
||||
wb_ctrl_dat_w => wb_ctrl_dat_w,
|
||||
wb_ctrl_dat_r => wb_ctrl_dat_r,
|
||||
wb_ctrl_sel => wb_ctrl_sel,
|
||||
wb_ctrl_cyc => wb_ctrl_cyc,
|
||||
wb_ctrl_stb => wb_ctrl_stb,
|
||||
wb_ctrl_ack => wb_ctrl_ack,
|
||||
wb_ctrl_we => wb_ctrl_we,
|
||||
wb_ctrl_cti => "000",
|
||||
wb_ctrl_bte => "00",
|
||||
wb_ctrl_err => open,
|
||||
user_port_native_0_cmd_valid => user_port0_cmd_valid,
|
||||
user_port_native_0_cmd_ready => user_port0_cmd_ready,
|
||||
user_port_native_0_cmd_we => user_port0_cmd_we,
|
||||
user_port_native_0_cmd_addr => user_port0_cmd_addr,
|
||||
user_port_native_0_wdata_valid => user_port0_wdata_valid,
|
||||
user_port_native_0_wdata_ready => user_port0_wdata_ready,
|
||||
user_port_native_0_wdata_we => user_port0_wdata_we,
|
||||
user_port_native_0_wdata_data => user_port0_wdata_data,
|
||||
user_port_native_0_rdata_valid => user_port0_rdata_valid,
|
||||
user_port_native_0_rdata_ready => user_port0_rdata_ready,
|
||||
user_port_native_0_rdata_data => user_port0_rdata_data
|
||||
);
|
||||
|
||||
end architecture behaviour;
|
||||
@@ -1443,7 +1443,7 @@ e8010010ebc1fff0
|
||||
203a4b4c43202020
|
||||
7a484d20646c6c25
|
||||
000000000000000a
|
||||
6138393331393333
|
||||
6131333764343635
|
||||
0000000000000000
|
||||
0033306536316430
|
||||
4d4152446574694c
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//--------------------------------------------------------------------------------
|
||||
// Auto-generated by Migen (0d16e03) & LiteX (3391398a) on 2020-05-21 19:21:29
|
||||
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-22 17:57:18
|
||||
//--------------------------------------------------------------------------------
|
||||
module litedram_core(
|
||||
input wire clk,
|
||||
|
||||
1
litedram/generated/sim/init-cpu.txt
Normal file
1
litedram/generated/sim/init-cpu.txt
Normal file
@@ -0,0 +1 @@
|
||||
none
|
||||
72
litedram/generated/sim/litedram-initmem.vhdl
Normal file
72
litedram/generated/sim/litedram-initmem.vhdl
Normal file
@@ -0,0 +1,72 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity dram_init_mem is
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
wb_in : in wb_io_master_out;
|
||||
wb_out : out wb_io_slave_out
|
||||
);
|
||||
end entity dram_init_mem;
|
||||
|
||||
architecture rtl of dram_init_mem is
|
||||
|
||||
constant INIT_RAM_SIZE : integer := 16384;
|
||||
constant INIT_RAM_ABITS :integer := 14;
|
||||
constant INIT_RAM_FILE : string := "litedram/generated/sim/litedram_core.init";
|
||||
|
||||
type ram_t is array(0 to (INIT_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0);
|
||||
|
||||
impure function init_load_ram(name : string) return ram_t is
|
||||
file ram_file : text open read_mode is name;
|
||||
variable temp_word : std_logic_vector(63 downto 0);
|
||||
variable temp_ram : ram_t := (others => (others => '0'));
|
||||
variable ram_line : line;
|
||||
begin
|
||||
for i in 0 to (INIT_RAM_SIZE/8)-1 loop
|
||||
exit when endfile(ram_file);
|
||||
readline(ram_file, ram_line);
|
||||
hread(ram_line, temp_word);
|
||||
temp_ram(i*2) := temp_word(31 downto 0);
|
||||
temp_ram(i*2+1) := temp_word(63 downto 32);
|
||||
end loop;
|
||||
return temp_ram;
|
||||
end function;
|
||||
|
||||
signal init_ram : ram_t := init_load_ram(INIT_RAM_FILE);
|
||||
|
||||
attribute ram_style : string;
|
||||
attribute ram_style of init_ram: signal is "block";
|
||||
|
||||
begin
|
||||
|
||||
init_ram_0: process(clk)
|
||||
variable adr : integer;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
wb_out.ack <= '0';
|
||||
if (wb_in.cyc and wb_in.stb) = '1' then
|
||||
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
|
||||
if wb_in.we = '0' then
|
||||
wb_out.dat <= init_ram(adr);
|
||||
else
|
||||
for i in 0 to 3 loop
|
||||
if wb_in.sel(i) = '1' then
|
||||
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
|
||||
wb_in.dat(((i + 1) * 8) - 1 downto i * 8);
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
wb_out.ack <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
wb_out.stall <= '0';
|
||||
|
||||
end architecture rtl;
|
||||
1191
litedram/generated/sim/litedram_core.init
Normal file
1191
litedram/generated/sim/litedram_core.init
Normal file
File diff suppressed because it is too large
Load Diff
18236
litedram/generated/sim/litedram_core.v
Normal file
18236
litedram/generated/sim/litedram_core.v
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user