@ -67,6 +67,7 @@ entity soc is
 
		
	
		
			
					RAM_INIT_FILE      : string;
 
		
	
		
			
					CLK_FREQ           : positive;
 
		
	
		
			
					SIM                : boolean;
 
		
	
		
			
				        NCPUS              : positive := 1;
 
		
	
		
			
				        HAS_FPU            : boolean := true;
 
		
	
		
			
				        HAS_BTC            : boolean := true;
 
		
	
		
			
					DISABLE_FLATTEN_CORE : boolean := false;
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -148,20 +149,18 @@ end entity soc;
 
		
	
		
			
				 
		
	
		
			
				architecture behaviour of soc is
 
		
	
		
			
				 
		
	
		
			
				    subtype cpu_index_t is natural range 0 to NCPUS-1;
 
		
	
		
			
				    type dword_percpu_array is array(cpu_index_t) of std_ulogic_vector(63 downto 0);
 
		
	
		
			
				 
		
	
		
			
				    -- internal reset
 
		
	
		
			
				    signal soc_reset : std_ulogic;
 
		
	
		
			
				 
		
	
		
			
				    -- Wishbone master signals:
 
		
	
		
			
				    signal wishbone_dcore_in  : wishbone_slave_out;
 
		
	
		
			
				    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_out  : wishbone_master_out;
 
		
	
		
			
				 
		
	
		
			
				    -- Arbiter array (ghdl doesnt' support assigning the array
 
		
	
		
			
				    -- elements in the entity instantiation)
 
		
	
		
			
				    constant NUM_WB_MASTERS : positive := 4;
 
		
	
		
			
				    -- Arbiter array
 
		
	
		
			
				    constant NUM_WB_MASTERS : positive := NCPUS * 2 + 2;
 
		
	
		
			
				    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);
 
		
	
		
			
				 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -180,7 +179,7 @@ architecture behaviour of soc is
 
		
	
		
			
				 
		
	
		
			
				    -- Syscon signals
 
		
	
		
			
				    signal dram_at_0     : std_ulogic;
 
		
	
		
			
				    signal do_core_reset    : std_ulogic;
 
		
	
		
			
				    signal do_core_reset : std_ulogic_vector(NCPUS-1 downto 0);
 
		
	
		
			
				    signal alt_reset     : std_ulogic;
 
		
	
		
			
				    signal wb_syscon_in  : wb_io_master_out;
 
		
	
		
			
				    signal wb_syscon_out : wb_io_slave_out;
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -210,7 +209,7 @@ architecture behaviour of soc is
 
		
	
		
			
				    signal wb_xics_ics_out  : wb_io_slave_out;
 
		
	
		
			
				    signal int_level_in     : std_ulogic_vector(15 downto 0);
 
		
	
		
			
				    signal ics_to_icp       : ics_to_icp_t;
 
		
	
		
			
				    signal core_ext_irq     : std_ulogic;
 
		
	
		
			
				    signal core_ext_irq     : std_ulogic_vector(NCPUS-1 downto 0) := (others => '0');
 
		
	
		
			
				 
		
	
		
			
				    -- GPIO signals:
 
		
	
		
			
				    signal wb_gpio_in    : wb_io_master_out;
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -233,12 +232,12 @@ architecture behaviour of soc is
 
		
	
		
			
				    signal dmi_wb_dout  : std_ulogic_vector(63 downto 0);
 
		
	
		
			
				    signal dmi_wb_req   : std_ulogic;
 
		
	
		
			
				    signal dmi_wb_ack   : std_ulogic;
 
		
	
		
			
				    signal dmi_core_dout  : std_ulogic_vector(63 downto 0);
 
		
	
		
			
				    signal dmi_core_req   : std_ulogic;
 
		
	
		
			
				    signal dmi_core_ack   : std_ulogic;
 
		
	
		
			
				    signal dmi_core_dout  : dword_percpu_array;
 
		
	
		
			
				    signal dmi_core_req   : std_ulogic_vector(NCPUS-1 downto 0);
 
		
	
		
			
				    signal dmi_core_ack   : std_ulogic_vector(NCPUS-1 downto 0);
 
		
	
		
			
				 
		
	
		
			
				    -- Delayed/latched resets and alt_reset
 
		
	
		
			
				    signal rst_core    : std_ulogic;
 
		
	
		
			
				    signal rst_core    : std_ulogic_vector(NCPUS-1 downto 0);
 
		
	
		
			
				    signal rst_uart    : std_ulogic;
 
		
	
		
			
				    signal rst_xics    : std_ulogic;
 
		
	
		
			
				    signal rst_spi     : std_ulogic;
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -270,6 +269,8 @@ architecture behaviour of soc is
 
		
	
		
			
				    signal io_cycle_gpio      : std_ulogic;
 
		
	
		
			
				    signal io_cycle_external  : std_ulogic;
 
		
	
		
			
				 
		
	
		
			
				    signal core_run_out       : std_ulogic_vector(NCPUS-1 downto 0);
 
		
	
		
			
				 
		
	
		
			
				    function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is
 
		
	
		
			
				        variable wwb : wishbone_master_out;
 
		
	
		
			
				    begin
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -334,7 +335,9 @@ begin
 
		
	
		
			
				    resets: process(system_clk)
 
		
	
		
			
				    begin
 
		
	
		
			
				        if rising_edge(system_clk) then
 
		
	
		
			
				            rst_core    <= soc_reset or do_core_reset;
 
		
	
		
			
				            for i in 0 to NCPUS-1 loop
 
		
	
		
			
				                rst_core(i) <= soc_reset or do_core_reset(i);
 
		
	
		
			
				            end loop;
 
		
	
		
			
				            rst_uart    <= soc_reset;
 
		
	
		
			
				            rst_spi     <= soc_reset;
 
		
	
		
			
				            rst_xics    <= soc_reset;
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -347,11 +350,12 @@ begin
 
		
	
		
			
				        end if;
 
		
	
		
			
				    end process;
 
		
	
		
			
				 
		
	
		
			
				    -- Processor core
 
		
	
		
			
				    processor: entity work.core
 
		
	
		
			
				    -- Processor cores
 
		
	
		
			
				    processors: for i in 0 to NCPUS-1 generate
 
		
	
		
			
				        core: entity work.core
 
		
	
		
			
					generic map(
 
		
	
		
			
					    SIM => SIM,
 
		
	
		
			
				            CPU_INDEX => 0,
 
		
	
		
			
				            CPU_INDEX => i,
 
		
	
		
			
				            HAS_FPU => HAS_FPU,
 
		
	
		
			
				            HAS_BTC => HAS_BTC,
 
		
	
		
			
					    DISABLE_FLATTEN => DISABLE_FLATTEN_CORE,
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -367,32 +371,31 @@ begin
 
		
	
		
			
					    )
 
		
	
		
			
					port map(
 
		
	
		
			
					    clk => system_clk,
 
		
	
		
			
					    rst => rst_core,
 
		
	
		
			
					    rst => rst_core(i),
 
		
	
		
			
					    alt_reset => alt_reset_d,
 
		
	
		
			
				            run_out => run_out,
 
		
	
		
			
					    wishbone_insn_in => wishbone_icore_in,
 
		
	
		
			
					    wishbone_insn_out => wishbone_icore_out,
 
		
	
		
			
					    wishbone_data_in => wishbone_dcore_in,
 
		
	
		
			
					    wishbone_data_out => wishbone_dcore_out,
 
		
	
		
			
				            run_out => core_run_out(i),
 
		
	
		
			
					    wishbone_insn_in => wb_masters_in(i + NCPUS),
 
		
	
		
			
					    wishbone_insn_out => wb_masters_out(i + NCPUS),
 
		
	
		
			
					    wishbone_data_in => wb_masters_in(i),
 
		
	
		
			
					    wishbone_data_out => wb_masters_out(i),
 
		
	
		
			
				            wb_snoop_in => wb_snoop,
 
		
	
		
			
					    dmi_addr => dmi_addr(3 downto 0),
 
		
	
		
			
					    dmi_dout => dmi_core_dout,
 
		
	
		
			
					    dmi_dout => dmi_core_dout(i),
 
		
	
		
			
					    dmi_din => dmi_dout,
 
		
	
		
			
					    dmi_wr => dmi_wr,
 
		
	
		
			
					    dmi_ack => dmi_core_ack,
 
		
	
		
			
					    dmi_req => dmi_core_req,
 
		
	
		
			
					    ext_irq => core_ext_irq
 
		
	
		
			
					    dmi_ack => dmi_core_ack(i),
 
		
	
		
			
					    dmi_req => dmi_core_req(i),
 
		
	
		
			
					    ext_irq => core_ext_irq(i)
 
		
	
		
			
					    );
 
		
	
		
			
				    end generate;
 
		
	
		
			
				 
		
	
		
			
				    run_out <= or (core_run_out);
 
		
	
		
			
				 
		
	
		
			
				    -- Wishbone bus master arbiter & mux
 
		
	
		
			
				    wb_masters_out <= (0 => wishbone_dcore_out,
 
		
	
		
			
						       1 => wishbone_icore_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_dma_in   <= wishbone_narrow_data(wb_masters_in(2), wishbone_dma_out.adr);
 
		
	
		
			
				    wishbone_debug_in <= wb_masters_in(3);
 
		
	
		
			
				    wb_masters_out(2*NCPUS)     <= wishbone_widen_data(wishbone_dma_out);
 
		
	
		
			
				    wb_masters_out(2*NCPUS + 1) <= wishbone_debug_out;
 
		
	
		
			
				    wishbone_dma_in   <= wishbone_narrow_data(wb_masters_in(2*NCPUS), wishbone_dma_out.adr);
 
		
	
		
			
				    wishbone_debug_in <= wb_masters_in(2*NCPUS + 1);
 
		
	
		
			
				    wishbone_arbiter_0: entity work.wishbone_arbiter
 
		
	
		
			
					generic map(
 
		
	
		
			
					    NUM_MASTERS => NUM_WB_MASTERS
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -780,6 +783,7 @@ begin
 
		
	
		
			
				    -- Syscon slave
 
		
	
		
			
				    syscon0: entity work.syscon
 
		
	
		
			
					generic map(
 
		
	
		
			
				            NCPUS => NCPUS,
 
		
	
		
			
					    HAS_UART => true,
 
		
	
		
			
					    HAS_DRAM => HAS_DRAM,
 
		
	
		
			
					    BRAM_SIZE => MEMORY_SIZE,
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -950,7 +954,7 @@ begin
 
		
	
		
			
					    wb_in => wb_xics_icp_in,
 
		
	
		
			
					    wb_out => wb_xics_icp_out,
 
		
	
		
			
				            ics_in => ics_to_icp,
 
		
	
		
			
					    core_irq_out => core_ext_irq
 
		
	
		
			
					    core_irq_out => core_ext_irq(0)
 
		
	
		
			
					    );
 
		
	
		
			
				 
		
	
		
			
				    xics_ics: entity work.xics_ics
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -1034,15 +1038,15 @@ begin
 
		
	
		
			
					    );
 
		
	
		
			
				 
		
	
		
			
				    -- DMI interconnect
 
		
	
		
			
				    dmi_intercon: process(dmi_addr, dmi_req,
 
		
	
		
			
							  dmi_wb_ack, dmi_wb_dout,
 
		
	
		
			
							  dmi_core_ack, dmi_core_dout)
 
		
	
		
			
				    dmi_intercon: process(all)
 
		
	
		
			
				 
		
	
		
			
					-- DMI address map (each address is a full 64-bit register)
 
		
	
		
			
					--
 
		
	
		
			
					-- Offset:   Size:    Slave:
 
		
	
		
			
					--  0         4       Wishbone
 
		
	
		
			
					-- 10        16       Core
 
		
	
		
			
					-- 10        16       Core 0
 
		
	
		
			
				        -- 20        16       Core 1
 
		
	
		
			
				        -- ... and so on for NCPUS cores
 
		
	
		
			
				 
		
	
		
			
					type slave_type is (SLAVE_WB,
 
		
	
		
			
							    SLAVE_CORE,
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -1053,25 +1057,29 @@ begin
 
		
	
		
			
					slave := SLAVE_NONE;
 
		
	
		
			
					if std_match(dmi_addr, "000000--") then
 
		
	
		
			
					    slave := SLAVE_WB;
 
		
	
		
			
					elsif std_match(dmi_addr, "0001----") then
 
		
	
		
			
				        elsif not is_X(dmi_addr) and to_integer(unsigned(dmi_addr(7 downto 4))) <= NCPUS then
 
		
	
		
			
					    slave := SLAVE_CORE;
 
		
	
		
			
					end if;
 
		
	
		
			
				 
		
	
		
			
					-- DMI muxing
 
		
	
		
			
					dmi_wb_req <= '0';
 
		
	
		
			
					dmi_core_req <= '0';
 
		
	
		
			
				        dmi_core_req <= (others => '0');
 
		
	
		
			
				        dmi_din <= (others => '1');
 
		
	
		
			
				        dmi_ack <= dmi_req;
 
		
	
		
			
					case slave is
 
		
	
		
			
					when SLAVE_WB =>
 
		
	
		
			
					    dmi_wb_req <= dmi_req;
 
		
	
		
			
					    dmi_ack <= dmi_wb_ack;
 
		
	
		
			
					    dmi_din <= dmi_wb_dout;
 
		
	
		
			
					when SLAVE_CORE =>
 
		
	
		
			
					    dmi_core_req <= dmi_req;
 
		
	
		
			
					    dmi_ack <= dmi_core_ack;
 
		
	
		
			
					    dmi_din <= dmi_core_dout;
 
		
	
		
			
				            for i in 0 to NCPUS-1 loop
 
		
	
		
			
				                if not is_X(dmi_addr) and to_integer(unsigned(dmi_addr(7 downto 4))) = i + 1 then
 
		
	
		
			
				                    dmi_core_req(i) <= dmi_req;
 
		
	
		
			
				                    dmi_ack <= dmi_core_ack(i);
 
		
	
		
			
				                    dmi_din <= dmi_core_dout(i);
 
		
	
		
			
				                end if;
 
		
	
		
			
				            end loop;
 
		
	
		
			
					when others =>
 
		
	
		
			
					    dmi_ack <= dmi_req;
 
		
	
		
			
					    dmi_din <= (others => '1');
 
		
	
		
			
					end case;
 
		
	
		
			
				 
		
	
		
			
					-- SIM magic exit