Line 1... |
Line 1... |
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
|
|
entity hellfire_cpu_if is
|
entity hfrisc_soc is
|
generic(
|
generic(
|
address_width: integer := 14;
|
address_width: integer := 14;
|
memory_file : string := "code.txt";
|
memory_file : string := "code.txt";
|
uart_support : string := "yes"
|
uart_support : string := "yes"
|
);
|
);
|
Line 12... |
Line 12... |
reset_in: in std_logic;
|
reset_in: in std_logic;
|
int_in: in std_logic;
|
int_in: in std_logic;
|
uart_read: in std_logic;
|
uart_read: in std_logic;
|
uart_write: out std_logic;
|
uart_write: out std_logic;
|
|
|
|
extio_in: in std_logic_vector(7 downto 0);
|
|
extio_out: out std_logic_vector(7 downto 0);
|
|
|
ram_address: out std_logic_vector(31 downto 2);
|
ram_address: out std_logic_vector(31 downto 2);
|
ram_data: inout std_logic_vector(31 downto 0);
|
ram_data: inout std_logic_vector(31 downto 0);
|
ram_ce1_n: out std_logic;
|
ram_ce1_n: out std_logic;
|
ram_ub1_n: out std_logic;
|
ram_ub1_n: out std_logic;
|
ram_lb1_n: out std_logic;
|
ram_lb1_n: out std_logic;
|
Line 23... |
Line 26... |
ram_ub2_n: out std_logic;
|
ram_ub2_n: out std_logic;
|
ram_lb2_n: out std_logic;
|
ram_lb2_n: out std_logic;
|
ram_we_n: out std_logic;
|
ram_we_n: out std_logic;
|
ram_oe_n: out std_logic
|
ram_oe_n: out std_logic
|
);
|
);
|
end hellfire_cpu_if;
|
end hfrisc_soc;
|
|
|
architecture interface of hellfire_cpu_if is
|
architecture top_level of hfrisc_soc is
|
signal clock, boot_enable, ram_enable_n, stall, stall_cpu, busy_cpu, irq_cpu, irq_ack_cpu, exception_cpu, data_access_cpu, ram_dly, rff1, reset: std_logic;
|
signal clock, boot_enable, ram_enable_n, stall, stall_cpu, irq_cpu, irq_ack_cpu, exception_cpu, data_access_cpu, ram_dly, rff1, reset: std_logic;
|
signal address, data_read, data_write, data_read_boot, data_read_ram, irq_vector_cpu, inst_addr_cpu, inst_in_cpu, data_addr_cpu, data_in_cpu, data_out_cpu: std_logic_vector(31 downto 0);
|
signal address, data_read, data_write, data_read_boot, data_read_ram, irq_vector_cpu, address_cpu, data_in_cpu, data_out_cpu: std_logic_vector(31 downto 0);
|
signal ext_irq: std_logic_vector(7 downto 0);
|
|
signal data_we, data_w_cpu: std_logic_vector(3 downto 0);
|
signal data_we, data_w_cpu: std_logic_vector(3 downto 0);
|
|
|
signal we_n_next : std_logic;
|
signal we_n_next : std_logic;
|
signal we_n_reg : std_logic;
|
signal we_n_reg : std_logic;
|
signal data_reg : std_logic_vector(31 downto 0);
|
signal data_reg : std_logic_vector(31 downto 0);
|
begin
|
begin
|
-- clock divider (25MHz clock from 50MHz main clock for Spartan3 Starter Kit)
|
-- clock divider (25MHz clock from 50MHz main clock for Spartan3 Starter Kit)
|
process (reset_in, clk_in, clock)
|
process (reset_in, clk_in, clock, we_n_next)
|
begin
|
begin
|
if reset_in = '1' then
|
if reset_in = '1' then
|
clock <= '0';
|
clock <= '0';
|
else
|
else
|
if clk_in'event and clk_in='1' then
|
if clk_in'event and clk_in='1' then
|
clock <= not clock;
|
clock <= not clock;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
|
if reset_in = '1' then
|
|
we_n_reg <= '1';
|
|
elsif rising_edge(clk_in) then
|
|
we_n_reg <= we_n_next or not clock;
|
|
end if;
|
|
|
|
if reset_in = '1' then
|
|
data_read_ram <= (others => '0');
|
|
elsif rising_edge(clock) then
|
|
data_read_ram <= ram_data;
|
|
end if;
|
end process;
|
end process;
|
|
|
-- reset synchronizer
|
-- reset synchronizer
|
process (clock, reset_in)
|
process (clock, reset_in)
|
begin
|
begin
|
Line 59... |
Line 73... |
rff1 <= '0';
|
rff1 <= '0';
|
reset <= rff1;
|
reset <= rff1;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
process (reset, clock, ext_irq, ram_enable_n, ram_data)
|
|
|
process (reset, clock, ram_enable_n)
|
begin
|
begin
|
if reset = '1' then
|
if reset = '1' then
|
data_read_ram <= (others => '0');
|
|
ram_dly <= '0';
|
ram_dly <= '0';
|
ext_irq <= x"00";
|
|
elsif clock'event and clock = '1' then
|
elsif clock'event and clock = '1' then
|
data_read_ram <= ram_data;
|
|
ram_dly <= not ram_enable_n;
|
ram_dly <= not ram_enable_n;
|
ext_irq <= "0000000" & int_in;
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
stall <= '0';
|
stall <= '0';
|
boot_enable <= '1' when address(31 downto 28) = "0000" else '0';
|
boot_enable <= '1' when address(31 downto 28) = "0000" else '0';
|
data_read <= data_read_boot when address(31 downto 28) = "0000" and ram_dly = '0' else data_read_ram;
|
data_read <= data_read_boot when address(31 downto 28) = "0000" and ram_dly = '0' else data_read_ram;
|
|
|
-- HF-RISCV core
|
-- HF-RISC core
|
core: entity work.datapath
|
core: entity work.datapath
|
port map( clock => clock,
|
port map( clock => clock,
|
reset => reset,
|
reset => reset,
|
stall => stall_cpu,
|
stall => stall_cpu,
|
busy => busy_cpu,
|
|
irq_vector => irq_vector_cpu,
|
irq_vector => irq_vector_cpu,
|
irq => irq_cpu,
|
irq => irq_cpu,
|
irq_ack => irq_ack_cpu,
|
irq_ack => irq_ack_cpu,
|
exception => exception_cpu,
|
exception => exception_cpu,
|
inst_addr => inst_addr_cpu,
|
address => address_cpu,
|
inst_in => inst_in_cpu,
|
|
data_addr => data_addr_cpu,
|
|
data_in => data_in_cpu,
|
data_in => data_in_cpu,
|
data_out => data_out_cpu,
|
data_out => data_out_cpu,
|
data_w => data_w_cpu,
|
data_w => data_w_cpu,
|
data_access => data_access_cpu
|
data_access => data_access_cpu
|
);
|
);
|
Line 107... |
Line 115... |
reset => reset,
|
reset => reset,
|
|
|
stall => stall,
|
stall => stall,
|
|
|
stall_cpu => stall_cpu,
|
stall_cpu => stall_cpu,
|
busy_cpu => busy_cpu,
|
|
irq_vector_cpu => irq_vector_cpu,
|
irq_vector_cpu => irq_vector_cpu,
|
irq_cpu => irq_cpu,
|
irq_cpu => irq_cpu,
|
irq_ack_cpu => irq_ack_cpu,
|
irq_ack_cpu => irq_ack_cpu,
|
exception_cpu => exception_cpu,
|
exception_cpu => exception_cpu,
|
inst_addr_cpu => inst_addr_cpu,
|
address_cpu => address_cpu,
|
inst_in_cpu => inst_in_cpu,
|
|
data_addr_cpu => data_addr_cpu,
|
|
data_in_cpu => data_in_cpu,
|
data_in_cpu => data_in_cpu,
|
data_out_cpu => data_out_cpu,
|
data_out_cpu => data_out_cpu,
|
data_w_cpu => data_w_cpu,
|
data_w_cpu => data_w_cpu,
|
data_access_cpu => data_access_cpu,
|
data_access_cpu => data_access_cpu,
|
|
|
addr_mem => address,
|
addr_mem => address,
|
data_read_mem => data_read,
|
data_read_mem => data_read,
|
data_write_mem => data_write,
|
data_write_mem => data_write,
|
data_we_mem => data_we,
|
data_we_mem => data_we,
|
extio_in => ext_irq,
|
extio_in => extio_in,
|
extio_out => open,
|
extio_out => extio_out,
|
uart_read => uart_read,
|
uart_read => uart_read,
|
uart_write => uart_write
|
uart_write => uart_write
|
);
|
);
|
|
|
-- instruction and data memory (boot RAM)
|
-- instruction and data memory (boot RAM)
|
Line 149... |
Line 154... |
-- these SRAMs have 16-bit words, so we use both chips and access each using low and
|
-- these SRAMs have 16-bit words, so we use both chips and access each using low and
|
-- high banks. using this arrangement, we have byte addressable 32-bit words.
|
-- high banks. using this arrangement, we have byte addressable 32-bit words.
|
-- the address bus is controlled directly by the CPU.
|
-- the address bus is controlled directly by the CPU.
|
ram_enable_n <= '0' when address(31 downto 28) = "0100" else '1';
|
ram_enable_n <= '0' when address(31 downto 28) = "0100" else '1';
|
ram_address <= address(31 downto 2);
|
ram_address <= address(31 downto 2);
|
|
ram_we_n <= we_n_reg;
|
|
|
ram_control:
|
ram_control:
|
process(clock, ram_enable_n, data_we, data_write)
|
process(clock, ram_enable_n, data_we, data_write)
|
begin
|
begin
|
if ram_enable_n = '0' then --SRAM
|
if ram_enable_n = '0' then --SRAM
|
Line 162... |
Line 168... |
ram_data <= (others => 'Z');
|
ram_data <= (others => 'Z');
|
ram_ub1_n <= '0';
|
ram_ub1_n <= '0';
|
ram_lb1_n <= '0';
|
ram_lb1_n <= '0';
|
ram_ub2_n <= '0';
|
ram_ub2_n <= '0';
|
ram_lb2_n <= '0';
|
ram_lb2_n <= '0';
|
ram_we_n <= '1';
|
we_n_next <= '1';
|
ram_oe_n <= '0';
|
ram_oe_n <= '0';
|
else -- write
|
else -- write
|
|
if clock = '1' then
|
|
ram_data <= (others => 'Z');
|
|
else
|
ram_data <= data_write;
|
ram_data <= data_write;
|
|
end if;
|
ram_ub1_n <= not data_we(3);
|
ram_ub1_n <= not data_we(3);
|
ram_lb1_n <= not data_we(2);
|
ram_lb1_n <= not data_we(2);
|
ram_ub2_n <= not data_we(1);
|
ram_ub2_n <= not data_we(1);
|
ram_lb2_n <= not data_we(0);
|
ram_lb2_n <= not data_we(0);
|
if clock = '0' then
|
we_n_next <= '0';
|
ram_we_n <= '0';
|
|
else
|
|
ram_we_n <= '1';
|
|
end if;
|
|
ram_oe_n <= '1';
|
ram_oe_n <= '1';
|
end if;
|
end if;
|
else
|
else
|
ram_data <= (others => 'Z');
|
ram_data <= (others => 'Z');
|
ram_ce1_n <= '1';
|
ram_ce1_n <= '1';
|
ram_ub1_n <= '1';
|
ram_ub1_n <= '1';
|
ram_lb1_n <= '1';
|
ram_lb1_n <= '1';
|
ram_ce2_n <= '1';
|
ram_ce2_n <= '1';
|
ram_ub2_n <= '1';
|
ram_ub2_n <= '1';
|
ram_lb2_n <= '1';
|
ram_lb2_n <= '1';
|
ram_we_n <= '1';
|
we_n_next <= '1';
|
ram_oe_n <= '1';
|
ram_oe_n <= '1';
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
end interface;
|
end top_level;
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|