mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-02-26 08:43:26 +00:00
@@ -37,6 +37,8 @@ entity core is
|
||||
wishbone_data_in : in wishbone_slave_out;
|
||||
wishbone_data_out : out wishbone_master_out;
|
||||
|
||||
wb_snoop_in : in wishbone_master_out;
|
||||
|
||||
dmi_addr : in std_ulogic_vector(3 downto 0);
|
||||
dmi_din : in std_ulogic_vector(63 downto 0);
|
||||
dmi_dout : out std_ulogic_vector(63 downto 0);
|
||||
@@ -241,6 +243,7 @@ begin
|
||||
stall_out => icache_stall_out,
|
||||
wishbone_out => wishbone_insn_out,
|
||||
wishbone_in => wishbone_insn_in,
|
||||
wb_snoop_in => wb_snoop_in,
|
||||
log_out => log_data(96 downto 43)
|
||||
);
|
||||
|
||||
@@ -423,6 +426,7 @@ begin
|
||||
stall_out => dcache_stall_out,
|
||||
wishbone_in => wishbone_data_in,
|
||||
wishbone_out => wishbone_data_out,
|
||||
snoop_in => wb_snoop_in,
|
||||
log_out => log_data(170 downto 151)
|
||||
);
|
||||
|
||||
|
||||
48
dcache.vhdl
48
dcache.vhdl
@@ -39,6 +39,8 @@ entity dcache is
|
||||
m_in : in MmuToDcacheType;
|
||||
m_out : out DcacheToMmuType;
|
||||
|
||||
snoop_in : in wishbone_master_out := wishbone_master_out_init;
|
||||
|
||||
stall_out : out std_ulogic;
|
||||
|
||||
wishbone_out : out wishbone_master_out;
|
||||
@@ -415,6 +417,11 @@ architecture rtl of dcache is
|
||||
type tlb_plru_out_t is array(tlb_index_t) of std_ulogic_vector(TLB_WAY_BITS-1 downto 0);
|
||||
signal tlb_plru_victim : tlb_plru_out_t;
|
||||
|
||||
signal snoop_tag_set : cache_tags_set_t;
|
||||
signal snoop_valid : std_ulogic;
|
||||
signal snoop_wrtag : cache_tag_t;
|
||||
signal snoop_index : index_t;
|
||||
|
||||
--
|
||||
-- Helper functions to decode incoming requests
|
||||
--
|
||||
@@ -528,7 +535,8 @@ begin
|
||||
assert LINE_SIZE mod ROW_SIZE = 0 report "LINE_SIZE not multiple of ROW_SIZE" severity FAILURE;
|
||||
assert ispow2(LINE_SIZE) report "LINE_SIZE not power of 2" severity FAILURE;
|
||||
assert ispow2(NUM_LINES) report "NUM_LINES not power of 2" severity FAILURE;
|
||||
assert ispow2(ROW_PER_LINE) report "ROW_PER_LINE not power of 2" severity FAILURE;
|
||||
assert ispow2(ROW_PER_LINE) and ROW_PER_LINE > 1
|
||||
report "ROW_PER_LINE not power of 2 greater than 1" severity FAILURE;
|
||||
assert (ROW_BITS = INDEX_BITS + ROW_LINEBITS)
|
||||
report "geometry bits don't add up" severity FAILURE;
|
||||
assert (LINE_OFF_BITS = ROW_OFF_BITS + ROW_LINEBITS)
|
||||
@@ -783,6 +791,24 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Cache tag RAM second read port, for snooping
|
||||
cache_tag_read_2 : process(clk)
|
||||
variable addr : std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0);
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
addr := (others => '0');
|
||||
addr(snoop_in.adr'left downto 0) := snoop_in.adr;
|
||||
snoop_tag_set <= cache_tags(get_index(addr));
|
||||
snoop_wrtag <= get_tag(addr);
|
||||
snoop_index <= get_index(addr);
|
||||
-- Don't snoop our own cycles
|
||||
snoop_valid <= '0';
|
||||
if not (r1.wb.cyc = '1' and wishbone_in.stall = '0') then
|
||||
snoop_valid <= snoop_in.cyc and snoop_in.stb and snoop_in.we;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Cache request parsing and hit detection
|
||||
dcache_request : process(all)
|
||||
variable is_hit : std_ulogic;
|
||||
@@ -1293,6 +1319,13 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Do invalidations from snooped stores to memory
|
||||
for i in way_t loop
|
||||
if snoop_valid = '1' and read_tag(i, snoop_tag_set) = snoop_wrtag then
|
||||
cache_valids(snoop_index)(i) <= '0';
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
if r1.write_tag = '1' then
|
||||
-- Store new tag in selected way
|
||||
for i in 0 to NUM_WAYS-1 loop
|
||||
@@ -1425,18 +1458,11 @@ begin
|
||||
end case;
|
||||
|
||||
when RELOAD_WAIT_ACK =>
|
||||
-- Requests are all sent if stb is 0
|
||||
stbs_done := r1.wb.stb = '0';
|
||||
|
||||
-- If we are still sending requests, was one accepted ?
|
||||
if wishbone_in.stall = '0' and not stbs_done then
|
||||
-- That was the last word ? We are done sending. Clear
|
||||
-- stb and set stbs_done so we can handle an eventual last
|
||||
-- ack on the same cycle.
|
||||
--
|
||||
if wishbone_in.stall = '0' and r1.wb.stb = '1' then
|
||||
-- That was the last word ? We are done sending. Clear stb.
|
||||
if is_last_row_addr(r1.wb.adr, r1.end_row_ix) then
|
||||
r1.wb.stb <= '0';
|
||||
stbs_done := true;
|
||||
end if;
|
||||
|
||||
-- Calculate the next row address
|
||||
@@ -1467,7 +1493,7 @@ begin
|
||||
end if;
|
||||
|
||||
-- Check for completion
|
||||
if stbs_done and is_last_row(r1.store_row, r1.end_row_ix) then
|
||||
if is_last_row(r1.store_row, r1.end_row_ix) then
|
||||
-- Complete wishbone cycle
|
||||
r1.wb.cyc <= '0';
|
||||
|
||||
|
||||
@@ -72,6 +72,19 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/input_
|
||||
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_9 }];
|
||||
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_10 }];
|
||||
|
||||
# connection to Digilent PmodSD on JA
|
||||
set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
|
||||
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_cmd }];
|
||||
set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[0] }];
|
||||
set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
||||
set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[1] }];
|
||||
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[2] }];
|
||||
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
||||
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { sdcard_wp }];
|
||||
|
||||
# Put registers into IOBs to improve timing
|
||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdcard_*}]
|
||||
|
||||
################################################################################
|
||||
# PMOD header JB (high-speed, no protection resisters)
|
||||
################################################################################
|
||||
@@ -85,6 +98,16 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/input_
|
||||
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_9 }];
|
||||
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_10 }];
|
||||
|
||||
# connection to Digilent PmodSD on JB
|
||||
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
|
||||
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_cmd }];
|
||||
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[0] }];
|
||||
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
||||
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[1] }];
|
||||
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[2] }];
|
||||
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
||||
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sdcard_wp }];
|
||||
|
||||
################################################################################
|
||||
# PMOD header JC (high-speed, no protection resisters)
|
||||
################################################################################
|
||||
|
||||
@@ -26,7 +26,8 @@ entity toplevel is
|
||||
LOG_LENGTH : natural := 512;
|
||||
USE_LITEETH : boolean := false;
|
||||
UART_IS_16550 : boolean := false;
|
||||
HAS_UART1 : boolean := true
|
||||
HAS_UART1 : boolean := true;
|
||||
USE_LITESDCARD : boolean := false
|
||||
);
|
||||
port(
|
||||
ext_clk : in std_ulogic;
|
||||
@@ -74,6 +75,12 @@ entity toplevel is
|
||||
eth_col : in std_ulogic;
|
||||
eth_crs : in std_ulogic;
|
||||
|
||||
-- SD card
|
||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
||||
sdcard_cmd : inout std_ulogic;
|
||||
sdcard_clk : out std_ulogic;
|
||||
sdcard_cd : in std_ulogic;
|
||||
|
||||
-- DRAM wires
|
||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
@@ -110,6 +117,7 @@ architecture behaviour of toplevel is
|
||||
signal wb_ext_is_dram_csr : std_ulogic;
|
||||
signal wb_ext_is_dram_init : std_ulogic;
|
||||
signal wb_ext_is_eth : std_ulogic;
|
||||
signal wb_ext_is_sdcard : std_ulogic;
|
||||
|
||||
-- DRAM main data wishbone connection
|
||||
signal wb_dram_in : wishbone_master_out;
|
||||
@@ -122,6 +130,16 @@ architecture behaviour of toplevel is
|
||||
signal ext_irq_eth : std_ulogic;
|
||||
signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
|
||||
|
||||
-- LiteSDCard connection
|
||||
signal ext_irq_sdcard : std_ulogic := '0';
|
||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
||||
signal wb_sddma_in : wb_io_slave_out;
|
||||
signal wb_sddma_nr : wb_io_master_out;
|
||||
signal wb_sddma_ir : wb_io_slave_out;
|
||||
-- for conversion from non-pipelined wishbone to pipelined
|
||||
signal wb_sddma_stb_sent : std_ulogic;
|
||||
|
||||
-- Control/status
|
||||
signal core_alt_reset : std_ulogic;
|
||||
|
||||
@@ -184,7 +202,8 @@ begin
|
||||
LOG_LENGTH => LOG_LENGTH,
|
||||
HAS_LITEETH => USE_LITEETH,
|
||||
UART0_IS_16550 => UART_IS_16550,
|
||||
HAS_UART1 => HAS_UART1
|
||||
HAS_UART1 => HAS_UART1,
|
||||
HAS_SD_CARD => USE_LITESDCARD
|
||||
)
|
||||
port map (
|
||||
-- System signals
|
||||
@@ -208,15 +227,24 @@ begin
|
||||
|
||||
-- External interrupts
|
||||
ext_irq_eth => ext_irq_eth,
|
||||
ext_irq_sdcard => ext_irq_sdcard,
|
||||
|
||||
-- DRAM wishbone
|
||||
wb_dram_in => wb_dram_in,
|
||||
wb_dram_out => wb_dram_out,
|
||||
|
||||
-- IO wishbone
|
||||
wb_ext_io_in => wb_ext_io_in,
|
||||
wb_ext_io_out => wb_ext_io_out,
|
||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
||||
wb_ext_is_eth => wb_ext_is_eth,
|
||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
||||
|
||||
-- DMA wishbone
|
||||
wishbone_dma_in => wb_sddma_in,
|
||||
wishbone_dma_out => wb_sddma_out,
|
||||
|
||||
alt_reset => core_alt_reset
|
||||
);
|
||||
|
||||
@@ -523,8 +551,113 @@ begin
|
||||
ext_irq_eth <= '0';
|
||||
end generate;
|
||||
|
||||
-- SD card pmod
|
||||
has_sdcard : if USE_LITESDCARD generate
|
||||
component litesdcard_core port (
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
-- wishbone for accessing control registers
|
||||
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;
|
||||
-- wishbone for SD card core to use for DMA
|
||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
||||
wb_dma_cyc : out std_ulogic;
|
||||
wb_dma_stb : out std_ulogic;
|
||||
wb_dma_ack : in std_ulogic;
|
||||
wb_dma_we : out std_ulogic;
|
||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
||||
wb_dma_err : in std_ulogic;
|
||||
-- connections to SD card
|
||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
||||
sdcard_cmd : inout std_ulogic;
|
||||
sdcard_clk : out std_ulogic;
|
||||
sdcard_cd : in std_ulogic;
|
||||
irq : out std_ulogic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal wb_sdcard_cyc : std_ulogic;
|
||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
||||
|
||||
begin
|
||||
litesdcard : litesdcard_core
|
||||
port map (
|
||||
clk => system_clk,
|
||||
rst => soc_rst,
|
||||
wb_ctrl_adr => wb_sdcard_adr,
|
||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
||||
wb_ctrl_we => wb_ext_io_in.we,
|
||||
wb_ctrl_cti => "000",
|
||||
wb_ctrl_bte => "00",
|
||||
wb_ctrl_err => open,
|
||||
wb_dma_adr => wb_sddma_nr.adr,
|
||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
||||
wb_dma_sel => wb_sddma_nr.sel,
|
||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
||||
wb_dma_stb => wb_sddma_nr.stb,
|
||||
wb_dma_ack => wb_sddma_ir.ack,
|
||||
wb_dma_we => wb_sddma_nr.we,
|
||||
wb_dma_cti => open,
|
||||
wb_dma_bte => open,
|
||||
wb_dma_err => '0',
|
||||
sdcard_data => sdcard_data,
|
||||
sdcard_cmd => sdcard_cmd,
|
||||
sdcard_clk => sdcard_clk,
|
||||
sdcard_cd => sdcard_cd,
|
||||
irq => ext_irq_sdcard
|
||||
);
|
||||
|
||||
-- Gate cyc with chip select from SoC
|
||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
||||
|
||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(15 downto 2);
|
||||
|
||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
||||
|
||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
||||
-- non-acknowledged strobes
|
||||
process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
wb_sddma_out <= wb_sddma_nr;
|
||||
if wb_sddma_stb_sent = '1' or
|
||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
||||
wb_sddma_out.stb <= '0';
|
||||
end if;
|
||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
||||
wb_sddma_stb_sent <= '0';
|
||||
elsif wb_sddma_in.stall = '0' then
|
||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
||||
end if;
|
||||
wb_sddma_ir <= wb_sddma_in;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end generate;
|
||||
|
||||
-- Mux WB response on the IO bus
|
||||
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else wb_dram_ctrl_out;
|
||||
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
|
||||
wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
||||
wb_dram_ctrl_out;
|
||||
|
||||
leds_pwm : process(system_clk)
|
||||
begin
|
||||
|
||||
55
icache.vhdl
55
icache.vhdl
@@ -68,6 +68,8 @@ entity icache is
|
||||
wishbone_out : out wishbone_master_out;
|
||||
wishbone_in : in wishbone_slave_out;
|
||||
|
||||
wb_snoop_in : in wishbone_master_out := wishbone_master_out_init;
|
||||
|
||||
log_out : out std_ulogic_vector(53 downto 0)
|
||||
);
|
||||
end entity icache;
|
||||
@@ -220,8 +222,13 @@ architecture rtl of icache is
|
||||
signal plru_victim : plru_out_t;
|
||||
signal replace_way : way_t;
|
||||
|
||||
-- Memory write snoop signals
|
||||
signal snoop_valid : std_ulogic;
|
||||
signal snoop_index : index_t;
|
||||
signal snoop_hits : cache_way_valids_t;
|
||||
|
||||
-- Return the cache line index (tag index) for an address
|
||||
function get_index(addr: std_ulogic_vector(63 downto 0)) return index_t is
|
||||
function get_index(addr: std_ulogic_vector) return index_t is
|
||||
begin
|
||||
return to_integer(unsigned(addr(SET_SIZE_BITS - 1 downto LINE_OFF_BITS)));
|
||||
end;
|
||||
@@ -614,7 +621,10 @@ begin
|
||||
-- Cache miss/reload synchronous machine
|
||||
icache_miss : process(clk)
|
||||
variable tagset : cache_tags_set_t;
|
||||
variable stbs_done : boolean;
|
||||
variable tag : cache_tag_t;
|
||||
variable snoop_addr : std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0);
|
||||
variable snoop_tag : cache_tag_t;
|
||||
variable snoop_cache_tags : cache_tags_set_t;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
-- On reset, clear all valid bits to force misses
|
||||
@@ -633,13 +643,43 @@ begin
|
||||
|
||||
-- Not useful normally but helps avoiding tons of sim warnings
|
||||
r.wb.adr <= (others => '0');
|
||||
|
||||
snoop_valid <= '0';
|
||||
snoop_index <= 0;
|
||||
snoop_hits <= (others => '0');
|
||||
else
|
||||
-- Detect snooped writes and decode address into index and tag
|
||||
-- Since we never write, any write should be snooped
|
||||
snoop_valid <= wb_snoop_in.cyc and wb_snoop_in.stb and wb_snoop_in.we;
|
||||
snoop_addr := (others => '0');
|
||||
snoop_addr(wb_snoop_in.adr'left downto 0) := wb_snoop_in.adr;
|
||||
snoop_index <= get_index(snoop_addr);
|
||||
snoop_cache_tags := cache_tags(get_index(snoop_addr));
|
||||
snoop_tag := get_tag(snoop_addr, '0');
|
||||
snoop_hits <= (others => '0');
|
||||
for i in way_t loop
|
||||
tag := read_tag(i, snoop_cache_tags);
|
||||
-- Ignore endian bit in comparison
|
||||
tag(TAG_BITS - 1) := '0';
|
||||
if tag = snoop_tag then
|
||||
snoop_hits(i) <= '1';
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
-- Process cache invalidations
|
||||
if inval_in = '1' then
|
||||
for i in index_t loop
|
||||
cache_valids(i) <= (others => '0');
|
||||
end loop;
|
||||
r.store_valid <= '0';
|
||||
else
|
||||
-- Do invalidations from snooped stores to memory, one
|
||||
-- cycle after the address appears on wb_snoop_in.
|
||||
for i in way_t loop
|
||||
if snoop_valid = '1' and snoop_hits(i) = '1' then
|
||||
cache_valids(snoop_index)(i) <= '0';
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
-- Main state machine
|
||||
@@ -697,18 +737,13 @@ begin
|
||||
|
||||
r.state <= WAIT_ACK;
|
||||
end if;
|
||||
-- Requests are all sent if stb is 0
|
||||
stbs_done := r.wb.stb = '0';
|
||||
|
||||
-- If we are still sending requests, was one accepted ?
|
||||
if wishbone_in.stall = '0' and not stbs_done then
|
||||
-- That was the last word ? We are done sending. Clear
|
||||
-- stb and set stbs_done so we can handle an eventual last
|
||||
-- ack on the same cycle.
|
||||
if wishbone_in.stall = '0' and r.wb.stb = '1' then
|
||||
-- That was the last word ? We are done sending. Clear stb.
|
||||
--
|
||||
if is_last_row_addr(r.wb.adr, r.end_row_ix) then
|
||||
r.wb.stb <= '0';
|
||||
stbs_done := true;
|
||||
end if;
|
||||
|
||||
-- Calculate the next row address
|
||||
@@ -719,7 +754,7 @@ begin
|
||||
if wishbone_in.ack = '1' then
|
||||
r.rows_valid(r.store_row mod ROW_PER_LINE) <= '1';
|
||||
-- Check for completion
|
||||
if stbs_done and is_last_row(r.store_row, r.end_row_ix) then
|
||||
if is_last_row(r.store_row, r.end_row_ix) then
|
||||
-- Complete wishbone cycle
|
||||
r.wb.cyc <= '0';
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define DRAM_CTRL_BASE 0xc8000000 /* LiteDRAM control registers */
|
||||
#define LETH_CSR_BASE 0xc8020000 /* LiteEth CSR registers */
|
||||
#define LETH_SRAM_BASE 0xc8030000 /* LiteEth MMIO space */
|
||||
#define LSDC_CSR_BASE 0xc8040000 /* LiteSDCard MMIO space */
|
||||
#define SPI_FLASH_BASE 0xf0000000 /* SPI Flash memory map */
|
||||
#define DRAM_INIT_BASE 0xff000000 /* Internal DRAM init firmware */
|
||||
|
||||
@@ -40,6 +41,7 @@
|
||||
#define SYS_REG_INFO_HAS_LARGE_SYSCON (1ull << 5)
|
||||
#define SYS_REG_INFO_HAS_UART1 (1ull << 6)
|
||||
#define SYS_REG_INFO_HAS_ARTB (1ull << 7)
|
||||
#define SYS_REG_INFO_HAS_LITESDCARD (1ull << 8)
|
||||
#define SYS_REG_BRAMINFO 0x10
|
||||
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
|
||||
#define SYS_REG_DRAMINFO 0x18
|
||||
|
||||
27
litesdcard/fusesoc-add-files.py
Normal file
27
litesdcard/fusesoc-add-files.py
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python3
|
||||
from fusesoc.capi2.generator import Generator
|
||||
import os
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
class LiteSDCardGenerator(Generator):
|
||||
def run(self):
|
||||
board = self.config.get('board')
|
||||
|
||||
# Collect a bunch of directory path
|
||||
script_dir = os.path.dirname(sys.argv[0])
|
||||
gen_dir = os.path.join(script_dir, "generated", board)
|
||||
|
||||
print("Adding LiteSDCard for board... ", board)
|
||||
|
||||
# Add files to fusesoc
|
||||
files = []
|
||||
f = os.path.join(gen_dir, "litesdcard_core.v")
|
||||
files.append({f : {'file_type' : 'verilogSource'}})
|
||||
|
||||
self.add_files(files)
|
||||
|
||||
g = LiteSDCardGenerator()
|
||||
g.run()
|
||||
g.write()
|
||||
|
||||
35
litesdcard/gen-src/generate.sh
Executable file
35
litesdcard/gen-src/generate.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
TARGETS=arty
|
||||
|
||||
ME=$(realpath $0)
|
||||
echo ME=$ME
|
||||
MY_PATH=$(dirname $ME)
|
||||
echo MYPATH=$MY_PATH
|
||||
PARENT_PATH=$(realpath $MY_PATH/..)
|
||||
echo PARENT=$PARENT_PATH
|
||||
BUILD_PATH=$PARENT_PATH/build
|
||||
mkdir -p $BUILD_PATH
|
||||
GEN_PATH=$PARENT_PATH/generated
|
||||
mkdir -p $GEN_PATH
|
||||
|
||||
# Note litesdcard/gen.py doesn't parse a YAML file, instead it takes
|
||||
# a --vendor=xxx parameter, where xxx = xilinx or lattice. If we
|
||||
# want to generate litesdcard for ecp5 we'll have to invent a way to
|
||||
# map arty to xilinx and ecp5 to lattice
|
||||
|
||||
for i in $TARGETS
|
||||
do
|
||||
TARGET_BUILD_PATH=$BUILD_PATH/$i
|
||||
TARGET_GEN_PATH=$GEN_PATH/$i
|
||||
rm -rf $TARGET_BUILD_PATH
|
||||
rm -rf $TARGET_GEN_PATH
|
||||
mkdir -p $TARGET_BUILD_PATH
|
||||
mkdir -p $TARGET_GEN_PATH
|
||||
|
||||
echo "Generating $i in $TARGET_BUILD_PATH"
|
||||
(cd $TARGET_BUILD_PATH && litesdcard_gen)
|
||||
|
||||
cp $TARGET_BUILD_PATH/build/gateware/litesdcard_core.v $TARGET_GEN_PATH/
|
||||
done
|
||||
|
||||
4159
litesdcard/generated/arty/litesdcard_core.v
Normal file
4159
litesdcard/generated/arty/litesdcard_core.v
Normal file
File diff suppressed because it is too large
Load Diff
15
litesdcard/litesdcard.core
Normal file
15
litesdcard/litesdcard.core
Normal file
@@ -0,0 +1,15 @@
|
||||
CAPI=2:
|
||||
|
||||
name : :microwatt:litesdcard:0
|
||||
|
||||
generators:
|
||||
litesdcard_gen:
|
||||
interpreter: python3
|
||||
command: fusesoc-add-files.py
|
||||
description: Generate a litesdcard SD-card controller
|
||||
usage: |
|
||||
litesdcard_gen adds the pre-generated LiteX LiteSDCard SD-card controller
|
||||
based on the board type.
|
||||
|
||||
Parameters:
|
||||
board: The board type (arty)
|
||||
@@ -116,6 +116,9 @@ filesets:
|
||||
liteeth:
|
||||
depend : [":microwatt:liteeth"]
|
||||
|
||||
litesdcard:
|
||||
depend : [":microwatt:litesdcard"]
|
||||
|
||||
uart16550:
|
||||
depend : ["::uart16550"]
|
||||
|
||||
@@ -243,7 +246,7 @@ targets:
|
||||
|
||||
arty_a7-35-nodram:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific, litesdcard]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -256,18 +259,20 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu=false
|
||||
- has_btc=false
|
||||
- use_litesdcard
|
||||
tools:
|
||||
vivado: {part : xc7a35ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-35:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific, litesdcard]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
- use_litedram=true
|
||||
- use_liteeth=true
|
||||
- use_litesdcard
|
||||
- disable_flatten_core
|
||||
- no_bram
|
||||
- spi_flash_offset=3145728
|
||||
@@ -276,14 +281,14 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu=false
|
||||
- has_btc=false
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
generate: [litedram_arty, liteeth_arty, litesdcard_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a35ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-100-nodram:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific, litesdcard]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -296,18 +301,20 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu
|
||||
- has_btc
|
||||
- use_litesdcard
|
||||
tools:
|
||||
vivado: {part : xc7a100ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-100:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific, litesdcard]
|
||||
parameters:
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
- use_litedram=true
|
||||
- use_liteeth=true
|
||||
- use_litesdcard
|
||||
- disable_flatten_core
|
||||
- no_bram
|
||||
- spi_flash_offset=4194304
|
||||
@@ -316,7 +323,7 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu
|
||||
- has_btc
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
generate: [litedram_arty, liteeth_arty, litesdcard_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a100ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
@@ -354,6 +361,10 @@ generate:
|
||||
generator: liteeth_gen
|
||||
parameters: {board : arty}
|
||||
|
||||
litesdcard_arty:
|
||||
generator: litesdcard_gen
|
||||
parameters: {board : arty}
|
||||
|
||||
litedram_nexys_video:
|
||||
generator: litedram_gen
|
||||
parameters: {board : nexys-video}
|
||||
@@ -425,6 +436,12 @@ parameters:
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
use_litesdcard:
|
||||
datatype : bool
|
||||
description : Use LiteSDCard
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
uart_is_16550:
|
||||
datatype : bool
|
||||
description : Use 16550-compatible UART from OpenCores
|
||||
|
||||
74
soc.vhdl
74
soc.vhdl
@@ -32,6 +32,7 @@ use work.wishbone_types.all;
|
||||
-- 0xc8000000: LiteDRAM control (CSRs)
|
||||
-- 0xc8020000: LiteEth CSRs (*)
|
||||
-- 0xc8030000: LiteEth MMIO (*)
|
||||
-- 0xc8040000: LiteSDCard CSRs
|
||||
|
||||
-- (*) LiteEth must be a single aligned 32KB block as the CSRs and MMIOs
|
||||
-- are actually decoded as a single wishbone which LiteEth will
|
||||
@@ -45,6 +46,8 @@ use work.wishbone_types.all;
|
||||
--
|
||||
-- 0 : UART0
|
||||
-- 1 : Ethernet
|
||||
-- 2 : UART1
|
||||
-- 3 : SD card
|
||||
|
||||
entity soc is
|
||||
generic (
|
||||
@@ -74,7 +77,8 @@ entity soc is
|
||||
DCACHE_NUM_LINES : natural := 64;
|
||||
DCACHE_NUM_WAYS : natural := 2;
|
||||
DCACHE_TLB_SET_SIZE : natural := 64;
|
||||
DCACHE_TLB_NUM_WAYS : natural := 2
|
||||
DCACHE_TLB_NUM_WAYS : natural := 2;
|
||||
HAS_SD_CARD : boolean := false
|
||||
);
|
||||
port(
|
||||
rst : in std_ulogic;
|
||||
@@ -90,9 +94,15 @@ entity soc is
|
||||
wb_ext_is_dram_csr : out std_ulogic;
|
||||
wb_ext_is_dram_init : out std_ulogic;
|
||||
wb_ext_is_eth : out std_ulogic;
|
||||
wb_ext_is_sdcard : out std_ulogic;
|
||||
|
||||
-- external DMA wishbone with 32-bit data/address
|
||||
wishbone_dma_in : out wb_io_slave_out := wb_io_slave_out_init;
|
||||
wishbone_dma_out : in wb_io_master_out := wb_io_master_out_init;
|
||||
|
||||
-- External interrupts
|
||||
ext_irq_eth : in std_ulogic := '0';
|
||||
ext_irq_sdcard : in std_ulogic := '0';
|
||||
|
||||
-- UART0 signals:
|
||||
uart0_txd : out std_ulogic;
|
||||
@@ -121,18 +131,19 @@ architecture behaviour of soc is
|
||||
signal wishbone_dcore_out : wishbone_master_out;
|
||||
signal wishbone_icore_in : wishbone_slave_out;
|
||||
signal wishbone_icore_out : wishbone_master_out;
|
||||
signal wishbone_debug_in : wishbone_slave_out;
|
||||
signal wishbone_debug_in : wishbone_slave_out;
|
||||
signal wishbone_debug_out : wishbone_master_out;
|
||||
|
||||
-- Arbiter array (ghdl doesnt' support assigning the array
|
||||
-- elements in the entity instantiation)
|
||||
constant NUM_WB_MASTERS : positive := 3;
|
||||
constant NUM_WB_MASTERS : positive := 4;
|
||||
signal wb_masters_out : wishbone_master_out_vector(0 to NUM_WB_MASTERS-1);
|
||||
signal wb_masters_in : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1);
|
||||
|
||||
-- Wishbone master (output of arbiter):
|
||||
signal wb_master_in : wishbone_slave_out;
|
||||
signal wb_master_out : wishbone_master_out;
|
||||
signal wb_snoop : wishbone_master_out;
|
||||
|
||||
-- Main "IO" bus, from main slave decoder to the latch
|
||||
signal wb_io_in : wishbone_master_out;
|
||||
@@ -218,6 +229,37 @@ architecture behaviour of soc is
|
||||
SLAVE_IO_NONE);
|
||||
signal slave_io_dbg : slave_io_type;
|
||||
|
||||
function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is
|
||||
variable wwb : wishbone_master_out;
|
||||
begin
|
||||
wwb.adr := wb.adr & "00"; -- XXX note wrong adr usage in wishbone_master_out
|
||||
wwb.dat := wb.dat & wb.dat;
|
||||
wwb.sel := x"00";
|
||||
if wwb.adr(2) = '0' then
|
||||
wwb.sel(3 downto 0) := wb.sel;
|
||||
else
|
||||
wwb.sel(7 downto 4) := wb.sel;
|
||||
end if;
|
||||
wwb.cyc := wb.cyc;
|
||||
wwb.stb := wb.stb;
|
||||
wwb.we := wb.we;
|
||||
return wwb;
|
||||
end;
|
||||
|
||||
function wishbone_narrow_data(wwbs : wishbone_slave_out; adr : std_ulogic_vector(29 downto 0))
|
||||
return wb_io_slave_out is
|
||||
variable wbs : wb_io_slave_out;
|
||||
begin
|
||||
wbs.ack := wwbs.ack;
|
||||
wbs.stall := wwbs.stall;
|
||||
if adr(0) = '0' then
|
||||
wbs.dat := wwbs.dat(31 downto 0);
|
||||
else
|
||||
wbs.dat := wwbs.dat(63 downto 32);
|
||||
end if;
|
||||
return wbs;
|
||||
end;
|
||||
|
||||
-- This is the component exported by the 16550 compatible
|
||||
-- UART from FuseSoC.
|
||||
--
|
||||
@@ -242,6 +284,7 @@ architecture behaviour of soc is
|
||||
dcd_pad_i : in std_ulogic
|
||||
);
|
||||
end component;
|
||||
|
||||
begin
|
||||
|
||||
resets: process(system_clk)
|
||||
@@ -284,6 +327,7 @@ begin
|
||||
wishbone_insn_out => wishbone_icore_out,
|
||||
wishbone_data_in => wishbone_dcore_in,
|
||||
wishbone_data_out => wishbone_dcore_out,
|
||||
wb_snoop_in => wb_snoop,
|
||||
dmi_addr => dmi_addr(3 downto 0),
|
||||
dmi_dout => dmi_core_dout,
|
||||
dmi_din => dmi_dout,
|
||||
@@ -296,10 +340,12 @@ begin
|
||||
-- Wishbone bus master arbiter & mux
|
||||
wb_masters_out <= (0 => wishbone_dcore_out,
|
||||
1 => wishbone_icore_out,
|
||||
2 => wishbone_debug_out);
|
||||
2 => wishbone_widen_data(wishbone_dma_out),
|
||||
3 => wishbone_debug_out);
|
||||
wishbone_dcore_in <= wb_masters_in(0);
|
||||
wishbone_icore_in <= wb_masters_in(1);
|
||||
wishbone_debug_in <= wb_masters_in(2);
|
||||
wishbone_dma_in <= wishbone_narrow_data(wb_masters_in(2), wishbone_dma_out.adr);
|
||||
wishbone_debug_in <= wb_masters_in(3);
|
||||
wishbone_arbiter_0: entity work.wishbone_arbiter
|
||||
generic map(
|
||||
NUM_MASTERS => NUM_WB_MASTERS
|
||||
@@ -313,6 +359,18 @@ begin
|
||||
wb_slave_in => wb_master_in
|
||||
);
|
||||
|
||||
-- Snoop bus going to caches.
|
||||
-- Gate stb with stall so the caches don't see the stalled strobes.
|
||||
-- That way if the caches see a strobe when their wishbone is stalled,
|
||||
-- they know it is an access by another master.
|
||||
process(all)
|
||||
begin
|
||||
wb_snoop <= wb_master_out;
|
||||
if wb_master_in.stall = '1' then
|
||||
wb_snoop.stb <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Top level Wishbone slaves address decoder & mux
|
||||
--
|
||||
-- From CPU to BRAM, DRAM, IO, selected on top 3 bits and dram_at_0
|
||||
@@ -575,6 +633,7 @@ begin
|
||||
wb_ext_is_dram_csr <= '0';
|
||||
wb_ext_is_dram_init <= '0';
|
||||
wb_ext_is_eth <= '0';
|
||||
wb_ext_is_sdcard <= '0';
|
||||
|
||||
-- Default response, ack & return all 1's
|
||||
wb_sio_in.dat <= (others => '1');
|
||||
@@ -602,6 +661,9 @@ begin
|
||||
elsif wb_sio_out.adr(23 downto 16) = x"03" and HAS_LITEETH then
|
||||
wb_ext_is_eth <= '1';
|
||||
ext_valid := true;
|
||||
elsif wb_sio_out.adr(23 downto 16) = x"04" and HAS_SD_CARD then
|
||||
wb_ext_is_sdcard <= '1';
|
||||
ext_valid := true;
|
||||
end if;
|
||||
if ext_valid then
|
||||
wb_ext_io_in.cyc <= wb_sio_out.cyc;
|
||||
@@ -651,6 +713,7 @@ begin
|
||||
HAS_SPI_FLASH => HAS_SPI_FLASH,
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
||||
HAS_LITEETH => HAS_LITEETH,
|
||||
HAS_SD_CARD => HAS_SD_CARD,
|
||||
UART0_IS_16550 => UART0_IS_16550,
|
||||
HAS_UART1 => HAS_UART1
|
||||
)
|
||||
@@ -834,6 +897,7 @@ begin
|
||||
int_level_in(0) <= uart0_irq;
|
||||
int_level_in(1) <= ext_irq_eth;
|
||||
int_level_in(2) <= uart1_irq;
|
||||
int_level_in(3) <= ext_irq_sdcard;
|
||||
end process;
|
||||
|
||||
-- BRAM Memory slave
|
||||
|
||||
19
syscon.vhdl
19
syscon.vhdl
@@ -18,6 +18,7 @@ entity syscon is
|
||||
HAS_SPI_FLASH : boolean;
|
||||
SPI_FLASH_OFFSET : integer;
|
||||
HAS_LITEETH : boolean;
|
||||
HAS_SD_CARD : boolean;
|
||||
UART0_IS_16550 : boolean;
|
||||
HAS_UART1 : boolean
|
||||
);
|
||||
@@ -65,6 +66,7 @@ architecture behaviour of syscon is
|
||||
constant SYS_REG_INFO_HAS_LSYS : integer := 5; -- Has 6-bit address syscon
|
||||
constant SYS_REG_INFO_HAS_URT1 : integer := 6; -- Has second UART
|
||||
constant SYS_REG_INFO_HAS_ARTB : integer := 7; -- Has architected TB frequency
|
||||
constant SYS_REG_INFO_HAS_SDCARD : integer := 8; -- Has LiteSDCard SD-card interface
|
||||
|
||||
-- BRAMINFO contains the BRAM size in the bottom 52 bits
|
||||
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
|
||||
@@ -107,6 +109,7 @@ architecture behaviour of syscon is
|
||||
signal info_has_uart : std_ulogic;
|
||||
signal info_has_spif : std_ulogic;
|
||||
signal info_has_leth : std_ulogic;
|
||||
signal info_has_lsdc : std_ulogic;
|
||||
signal info_has_urt1 : std_ulogic;
|
||||
signal info_clk : std_ulogic_vector(39 downto 0);
|
||||
signal info_fl_off : std_ulogic_vector(31 downto 0);
|
||||
@@ -128,15 +131,17 @@ begin
|
||||
info_has_bram <= '1' when BRAM_SIZE /= 0 else '0';
|
||||
info_has_spif <= '1' when HAS_SPI_FLASH else '0';
|
||||
info_has_leth <= '1' when HAS_LITEETH else '0';
|
||||
info_has_lsdc <= '1' when HAS_SD_CARD else '0';
|
||||
info_has_urt1 <= '1' when HAS_UART1 else '0';
|
||||
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
|
||||
reg_info <= (SYS_REG_INFO_HAS_UART => info_has_uart,
|
||||
SYS_REG_INFO_HAS_DRAM => info_has_dram,
|
||||
SYS_REG_INFO_HAS_BRAM => info_has_bram,
|
||||
SYS_REG_INFO_HAS_SPIF => info_has_spif,
|
||||
SYS_REG_INFO_HAS_LETH => info_has_leth,
|
||||
SYS_REG_INFO_HAS_LSYS => '1',
|
||||
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
|
||||
reg_info <= (SYS_REG_INFO_HAS_UART => info_has_uart,
|
||||
SYS_REG_INFO_HAS_DRAM => info_has_dram,
|
||||
SYS_REG_INFO_HAS_BRAM => info_has_bram,
|
||||
SYS_REG_INFO_HAS_SPIF => info_has_spif,
|
||||
SYS_REG_INFO_HAS_LETH => info_has_leth,
|
||||
SYS_REG_INFO_HAS_SDCARD => info_has_lsdc,
|
||||
SYS_REG_INFO_HAS_LSYS => '1',
|
||||
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
|
||||
others => '0');
|
||||
|
||||
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
|
||||
|
||||
@@ -44,6 +44,8 @@ package wishbone_types is
|
||||
stb : std_ulogic;
|
||||
we : std_ulogic;
|
||||
end record;
|
||||
constant wb_io_master_out_init : wb_io_master_out := (adr => (others => '0'), dat => (others => '0'),
|
||||
sel => "0000", cyc => '0', stb => '0', we => '0');
|
||||
|
||||
type wb_io_slave_out is record
|
||||
dat : std_ulogic_vector(31 downto 0);
|
||||
|
||||
Reference in New Issue
Block a user