mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
syscon: Add syscon registers
These provides some info about the SoC (though it's still somewhat incomplete and needs more work, see comments). There's also a control register for selecting DRAM vs. BRAM at 0 (and for soft-resetting the SoC but that isn't wired up yet). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
2cef3005cd
commit
025cf5efe8
3
Makefile
3
Makefile
@ -71,7 +71,8 @@ rotator_tb.o: common.o glibc_random.o ppc_fx_insns.o insn_helpers.o rotator.o
|
||||
sim_console.o:
|
||||
sim_uart.o: wishbone_types.o sim_console.o
|
||||
xics.o: wishbone_types.o common.o
|
||||
soc.o: common.o wishbone_types.o core.o wishbone_arbiter.o sim_uart.o wishbone_bram_wrapper.o dmi_dtm_xilinx.o wishbone_debug_master.o xics.o
|
||||
soc.o: common.o wishbone_types.o core.o wishbone_arbiter.o sim_uart.o wishbone_bram_wrapper.o dmi_dtm_xilinx.o wishbone_debug_master.o xics.o syscon.o
|
||||
syscon.o: wishbone_types.o
|
||||
wishbone_arbiter.o: wishbone_types.o
|
||||
wishbone_types.o:
|
||||
writeback.o: common.o crhelpers.o
|
||||
|
||||
@ -25,7 +25,8 @@ begin
|
||||
SIM => true,
|
||||
MEMORY_SIZE => (384*1024),
|
||||
RAM_INIT_FILE => "main_ram.bin",
|
||||
RESET_LOW => false
|
||||
RESET_LOW => false,
|
||||
CLK_FREQ => 100000000
|
||||
)
|
||||
port map(
|
||||
rst => rst,
|
||||
|
||||
@ -92,7 +92,9 @@ begin
|
||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
||||
RESET_LOW => RESET_LOW,
|
||||
SIM => false,
|
||||
CLK_FREQ => CLK_FREQUENCY,
|
||||
HAS_DRAM => USE_LITEDRAM,
|
||||
DRAM_SIZE => 256 * 1024 * 1024,
|
||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
|
||||
)
|
||||
port map (
|
||||
|
||||
@ -75,7 +75,9 @@ begin
|
||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
||||
RESET_LOW => RESET_LOW,
|
||||
SIM => false,
|
||||
CLK_FREQ => CLK_FREQUENCY,
|
||||
HAS_DRAM => USE_LITEDRAM,
|
||||
DRAM_SIZE => 512 * 1024 * 1024,
|
||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
|
||||
)
|
||||
port map (
|
||||
|
||||
@ -156,7 +156,8 @@ void main(void)
|
||||
printf(" INFO: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x08));
|
||||
printf(" BRAMINFO: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x10));
|
||||
printf(" DRAMINFO: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x18));
|
||||
printf(" CTRL: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x20));
|
||||
printf(" CLKINFO: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x20));
|
||||
printf(" CTRL: %016llx\n", (unsigned long long)readq(SYSCON_BASE + 0x28));
|
||||
sdrinit();
|
||||
printf("Booting from BRAM...\n");
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@ filesets:
|
||||
- wishbone_bram_wrapper.vhdl
|
||||
- soc.vhdl
|
||||
- xics.vhdl
|
||||
- syscon.vhdl
|
||||
file_type : vhdlSource-2008
|
||||
|
||||
fpga:
|
||||
|
||||
49
soc.vhdl
49
soc.vhdl
@ -12,8 +12,9 @@ use work.wishbone_types.all;
|
||||
|
||||
-- Memory map:
|
||||
--
|
||||
-- 0x00000000: Block RAM
|
||||
-- 0x00000000: Block RAM (MEMORY_SIZE) or DRAM depending on syscon
|
||||
-- 0x40000000: DRAM (when present)
|
||||
-- 0xc0000000: SYSCON
|
||||
-- 0xc0002000: UART0
|
||||
-- 0xc0004000: XICS ICP
|
||||
-- 0xf0000000: Block RAM (aliased & repeated)
|
||||
@ -24,9 +25,11 @@ entity soc is
|
||||
MEMORY_SIZE : positive;
|
||||
RAM_INIT_FILE : string;
|
||||
RESET_LOW : boolean;
|
||||
CLK_FREQ : positive;
|
||||
SIM : boolean;
|
||||
DISABLE_FLATTEN_CORE : boolean := false;
|
||||
HAS_DRAM : boolean := false
|
||||
HAS_DRAM : boolean := false;
|
||||
DRAM_SIZE : integer := 0
|
||||
);
|
||||
port(
|
||||
rst : in std_ulogic;
|
||||
@ -67,6 +70,12 @@ architecture behaviour of soc is
|
||||
signal wb_master_in : wishbone_slave_out;
|
||||
signal wb_master_out : wishbone_master_out;
|
||||
|
||||
-- Syscon signals
|
||||
signal dram_at_0 : std_ulogic;
|
||||
signal core_reset : std_ulogic;
|
||||
signal wb_syscon_in : wishbone_master_out;
|
||||
signal wb_syscon_out : wishbone_slave_out;
|
||||
|
||||
-- UART0 signals:
|
||||
signal wb_uart0_in : wishbone_master_out;
|
||||
signal wb_uart0_out : wishbone_slave_out;
|
||||
@ -110,7 +119,7 @@ begin
|
||||
)
|
||||
port map(
|
||||
clk => system_clk,
|
||||
rst => rst,
|
||||
rst => rst or core_reset,
|
||||
alt_reset => alt_reset,
|
||||
wishbone_insn_in => wishbone_icore_in,
|
||||
wishbone_insn_out => wishbone_icore_out,
|
||||
@ -145,9 +154,10 @@ begin
|
||||
);
|
||||
|
||||
-- Wishbone slaves address decoder & mux
|
||||
slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out, wb_dram_out)
|
||||
slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out, wb_dram_out, wb_syscon_out)
|
||||
-- Selected slave
|
||||
type slave_type is (SLAVE_UART,
|
||||
type slave_type is (SLAVE_SYSCON,
|
||||
SLAVE_UART,
|
||||
SLAVE_BRAM,
|
||||
SLAVE_DRAM,
|
||||
SLAVE_DRAM_INIT,
|
||||
@ -161,13 +171,16 @@ begin
|
||||
-- Simple address decoder. Ignore top bits to save silicon for now
|
||||
slave := SLAVE_NONE;
|
||||
if std_match(wb_master_out.adr, x"0-------") then
|
||||
slave := SLAVE_BRAM;
|
||||
slave := SLAVE_DRAM when HAS_DRAM and dram_at_0 = '1' else
|
||||
SLAVE_BRAM;
|
||||
elsif std_match(wb_master_out.adr, x"FFFF----") then
|
||||
slave := SLAVE_DRAM_INIT;
|
||||
elsif std_match(wb_master_out.adr, x"F-------") then
|
||||
slave := SLAVE_BRAM;
|
||||
elsif std_match(wb_master_out.adr, x"4-------") and HAS_DRAM then
|
||||
slave := SLAVE_DRAM;
|
||||
elsif std_match(wb_master_out.adr, x"C0000---") then
|
||||
slave := SLAVE_SYSCON;
|
||||
elsif std_match(wb_master_out.adr, x"C0002---") then
|
||||
slave := SLAVE_UART;
|
||||
elsif std_match(wb_master_out.adr, x"C01-----") then
|
||||
@ -192,6 +205,8 @@ begin
|
||||
wb_dram_in.cyc <= '0';
|
||||
wb_dram_csr <= '0';
|
||||
wb_dram_init <= '0';
|
||||
wb_syscon_in <= wb_master_out;
|
||||
wb_syscon_in.cyc <= '0';
|
||||
case slave is
|
||||
when SLAVE_BRAM =>
|
||||
wb_bram_in.cyc <= wb_master_out.cyc;
|
||||
@ -207,6 +222,9 @@ begin
|
||||
wb_dram_in.cyc <= wb_master_out.cyc;
|
||||
wb_master_in <= wb_dram_out;
|
||||
wb_dram_csr <= '1';
|
||||
when SLAVE_SYSCON =>
|
||||
wb_syscon_in.cyc <= wb_master_out.cyc;
|
||||
wb_master_in <= wb_syscon_out;
|
||||
when SLAVE_UART =>
|
||||
wb_uart0_in.cyc <= wb_master_out.cyc;
|
||||
wb_master_in <= wb_uart0_out;
|
||||
@ -220,6 +238,25 @@ begin
|
||||
end case;
|
||||
end process slave_intercon;
|
||||
|
||||
-- Syscon slave
|
||||
syscon0: entity work.syscon
|
||||
generic map(
|
||||
HAS_UART => true,
|
||||
HAS_DRAM => HAS_DRAM,
|
||||
BRAM_SIZE => MEMORY_SIZE,
|
||||
DRAM_SIZE => DRAM_SIZE,
|
||||
CLK_FREQ => CLK_FREQ
|
||||
)
|
||||
port map(
|
||||
clk => system_clk,
|
||||
rst => rst,
|
||||
wishbone_in => wb_syscon_in,
|
||||
wishbone_out => wb_syscon_out,
|
||||
dram_at_0 => dram_at_0,
|
||||
core_reset => core_reset,
|
||||
soc_reset => open -- XXX TODO
|
||||
);
|
||||
|
||||
-- Simulated memory and UART
|
||||
|
||||
-- UART0 wishbone slave
|
||||
|
||||
136
syscon.vhdl
Normal file
136
syscon.vhdl
Normal file
@ -0,0 +1,136 @@
|
||||
-- syscon module, a bunch of misc global system control MMIO registers
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity syscon is
|
||||
generic (
|
||||
SIG_VALUE : std_ulogic_vector(63 downto 0) := x"f00daa5500010001";
|
||||
CLK_FREQ : integer;
|
||||
HAS_UART : boolean;
|
||||
HAS_DRAM : boolean;
|
||||
BRAM_SIZE : integer;
|
||||
DRAM_SIZE : integer
|
||||
);
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
|
||||
-- Wishbone ports:
|
||||
wishbone_in : in wishbone_master_out;
|
||||
wishbone_out : out wishbone_slave_out;
|
||||
|
||||
-- System control ports
|
||||
dram_at_0 : out std_ulogic;
|
||||
core_reset : out std_ulogic;
|
||||
soc_reset : out std_ulogic
|
||||
);
|
||||
end entity syscon;
|
||||
|
||||
|
||||
architecture behaviour of syscon is
|
||||
-- Register address bits
|
||||
constant SYS_REG_BITS : positive := 3;
|
||||
|
||||
-- Register addresses (matches wishbone addr downto 3, ie, 8 bytes per reg)
|
||||
constant SYS_REG_SIG : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000";
|
||||
constant SYS_REG_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001";
|
||||
constant SYS_REG_BRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "010";
|
||||
constant SYS_REG_DRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "011";
|
||||
constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "100";
|
||||
constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "101";
|
||||
|
||||
-- INFO register bits
|
||||
constant SYS_REG_INFO_HAS_UART : integer := 0;
|
||||
constant SYS_REG_INFO_HAS_DRAM : integer := 1;
|
||||
|
||||
-- BRAMINFO contains the BRAM size in the bottom 52 bits
|
||||
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
|
||||
-- (both have reserved top bits for future use)
|
||||
-- CLKINFO contains the CLK frequency is HZ in the bottom 40 bits
|
||||
|
||||
-- CTRL register bits
|
||||
constant SYS_REG_CTRL_BITS : positive := 3;
|
||||
constant SYS_REG_CTRL_DRAM_AT_0 : integer := 0;
|
||||
constant SYS_REG_CTRL_CORE_RESET : integer := 1;
|
||||
constant SYS_REG_CTRL_SOC_RESET : integer := 2;
|
||||
|
||||
-- Ctrl register
|
||||
signal reg_ctrl : std_ulogic_vector(SYS_REG_CTRL_BITS-1 downto 0);
|
||||
signal reg_ctrl_out : std_ulogic_vector(63 downto 0);
|
||||
|
||||
-- Others
|
||||
signal reg_info : std_ulogic_vector(63 downto 0);
|
||||
signal reg_braminfo : std_ulogic_vector(63 downto 0);
|
||||
signal reg_draminfo : std_ulogic_vector(63 downto 0);
|
||||
signal reg_clkinfo : std_ulogic_vector(63 downto 0);
|
||||
signal info_has_dram : std_ulogic;
|
||||
signal info_has_uart : std_ulogic;
|
||||
signal info_clk : std_ulogic_vector(39 downto 0);
|
||||
begin
|
||||
|
||||
-- Generated output signals
|
||||
dram_at_0 <= reg_ctrl(SYS_REG_CTRL_DRAM_AT_0);
|
||||
soc_reset <= reg_ctrl(SYS_REG_CTRL_SOC_RESET);
|
||||
core_reset <= reg_ctrl(SYS_REG_CTRL_CORE_RESET);
|
||||
|
||||
-- All register accesses are single cycle
|
||||
wishbone_out.ack <= wishbone_in.cyc and wishbone_in.stb;
|
||||
wishbone_out.stall <= '0';
|
||||
|
||||
-- Info register is hard wired
|
||||
info_has_uart <= '1' when HAS_UART else '0';
|
||||
info_has_dram <= '1' when HAS_DRAM else '0';
|
||||
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
|
||||
reg_info <= (0 => info_has_uart,
|
||||
1 => info_has_dram,
|
||||
others => '0');
|
||||
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
|
||||
reg_draminfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_SIZE, 52)) when HAS_DRAM
|
||||
else (others => '0');
|
||||
reg_clkinfo <= (39 downto 0 => info_clk,
|
||||
others => '0');
|
||||
|
||||
-- Control register read composition
|
||||
reg_ctrl_out <= (63 downto SYS_REG_CTRL_BITS => '0',
|
||||
SYS_REG_CTRL_BITS-1 downto 0 => reg_ctrl);
|
||||
|
||||
-- Register read mux
|
||||
with wishbone_in.adr(SYS_REG_BITS+2 downto 3) select wishbone_out.dat <=
|
||||
SIG_VALUE when SYS_REG_SIG,
|
||||
reg_info when SYS_REG_INFO,
|
||||
reg_braminfo when SYS_REG_BRAMINFO,
|
||||
reg_draminfo when SYS_REG_DRAMINFO,
|
||||
reg_clkinfo when SYS_REG_CLKINFO,
|
||||
reg_ctrl_out when SYS_REG_CTRL,
|
||||
(others => '0') when others;
|
||||
|
||||
-- Register writes
|
||||
regs_write: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if (rst) then
|
||||
reg_ctrl <= (others => '0');
|
||||
else
|
||||
if wishbone_in.cyc and wishbone_in.stb and wishbone_in.we then
|
||||
if wishbone_in.adr(SYS_REG_BITS+2 downto 3) = SYS_REG_CTRL then
|
||||
reg_ctrl(SYS_REG_CTRL_BITS-1 downto 0) <=
|
||||
wishbone_in.dat(SYS_REG_CTRL_BITS-1 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Reset auto-clear
|
||||
if reg_ctrl(SYS_REG_CTRL_SOC_RESET) = '1' then
|
||||
reg_ctrl(SYS_REG_CTRL_SOC_RESET) <= '0';
|
||||
end if;
|
||||
if reg_ctrl(SYS_REG_CTRL_CORE_RESET) = '1' then
|
||||
reg_ctrl(SYS_REG_CTRL_CORE_RESET) <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture behaviour;
|
||||
Loading…
x
Reference in New Issue
Block a user