OpenCores
URL https://opencores.org/ocsvn/hf-risc/hf-risc/trunk

Subversion Repositories hf-risc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /hf-risc/trunk/hf-risc
    from Rev 17 to Rev 18
    Reverse comparison

Rev 17 → Rev 18

/platform/spartan3_starterkit/spartan3.vhd
2,7 → 2,7
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity hellfire_cpu_if is
entity hfrisc_soc is
generic(
address_width: integer := 14;
memory_file : string := "code.txt";
14,11 → 14,11
uart_read: in std_logic;
uart_write: out std_logic
);
end hellfire_cpu_if;
end hfrisc_soc;
 
architecture interface of hellfire_cpu_if is
signal clock, boot_enable, ram_enable_n, stall, stall_cpu, busy_cpu, irq_cpu, irq_ack_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);
architecture top_level of hfrisc_soc is
signal clock, boot_enable, ram_enable_n, stall, stall_cpu, irq_cpu, irq_ack_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, 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_n_ram, data_w_cpu: std_logic_vector(3 downto 0);
begin
69,13 → 69,10
port map( clock => clock,
reset => reset,
stall => stall_cpu,
busy => busy_cpu,
irq_vector => irq_vector_cpu,
irq => irq_cpu,
irq_ack => irq_ack_cpu,
inst_addr => inst_addr_cpu,
inst_in => inst_in_cpu,
data_addr => data_addr_cpu,
address => address_cpu,
data_in => data_in_cpu,
data_out => data_out_cpu,
data_w => data_w_cpu,
94,13 → 91,10
stall => stall,
 
stall_cpu => stall_cpu,
busy_cpu => busy_cpu,
irq_vector_cpu => irq_vector_cpu,
irq_cpu => irq_cpu,
irq_ack_cpu => irq_ack_cpu,
inst_addr_cpu => inst_addr_cpu,
inst_in_cpu => inst_in_cpu,
data_addr_cpu => data_addr_cpu,
address_cpu => address_cpu,
data_in_cpu => data_in_cpu,
data_out_cpu => data_out_cpu,
data_w_cpu => data_w_cpu,
185,5 → 179,5
data_o => data_read_ram(31 downto 24)
);
 
end interface;
end top_level;
 
/platform/spartan3_starterkit/spartan3_SRAM.ucf
8,6 → 8,24
NET "uart_write" LOC = "R13"; #RX
NET "uart_read" LOC = "T13"; #TX
 
NET "extio_in<0>" LOC = "C5";
NET "extio_in<1>" LOC = "C6";
NET "extio_in<2>" LOC = "C7";
NET "extio_in<3>" LOC = "C8";
NET "extio_in<4>" LOC = "C9";
NET "extio_in<5>" LOC = "A3";
NET "extio_in<6>" LOC = "A4";
NET "extio_in<7>" LOC = "A5";
 
NET "extio_out<0>" LOC = "D5";
NET "extio_out<1>" LOC = "D6";
NET "extio_out<2>" LOC = "E7";
NET "extio_out<3>" LOC = "D7";
NET "extio_out<4>" LOC = "D8";
NET "extio_out<5>" LOC = "D10";
NET "extio_out<6>" LOC = "B4";
NET "extio_out<7>" LOC = "B5";
 
NET "ram_address<2>" LOC = "L5";
NET "ram_address<3>" LOC = "N3";
NET "ram_address<4>" LOC = "M4";
/platform/spartan3_starterkit/spartan3_SRAM.vhd
2,7 → 2,7
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity hellfire_cpu_if is
entity hfrisc_soc is
generic(
address_width: integer := 14;
memory_file : string := "code.txt";
14,6 → 14,9
uart_read: in 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_data: inout std_logic_vector(31 downto 0);
ram_ce1_n: out std_logic;
25,12 → 28,11
ram_we_n: out std_logic;
ram_oe_n: out std_logic
);
end hellfire_cpu_if;
end hfrisc_soc;
 
architecture interface of hellfire_cpu_if is
signal clock, boot_enable, ram_enable_n, stall, stall_cpu, busy_cpu, irq_cpu, irq_ack_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 ext_irq: std_logic_vector(7 downto 0);
architecture top_level of hfrisc_soc is
signal clock, boot_enable, ram_enable_n, stall, stall_cpu, irq_cpu, irq_ack_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, address_cpu, data_in_cpu, data_out_cpu: std_logic_vector(31 downto 0);
signal data_we, data_w_cpu: std_logic_vector(3 downto 0);
 
signal we_n_next : std_logic;
74,14 → 76,12
end process;
 
 
process (reset, clock, ext_irq, ram_enable_n)
process (reset, clock, ram_enable_n)
begin
if reset = '1' then
ram_dly <= '0';
ext_irq <= x"00";
elsif clock'event and clock = '1' then
ram_dly <= not ram_enable_n;
ext_irq <= "0000000" & int_in;
end if;
end process;
 
94,13 → 94,10
port map( clock => clock,
reset => reset,
stall => stall_cpu,
busy => busy_cpu,
irq_vector => irq_vector_cpu,
irq => irq_cpu,
irq_ack => irq_ack_cpu,
inst_addr => inst_addr_cpu,
inst_in => inst_in_cpu,
data_addr => data_addr_cpu,
address => address_cpu,
data_in => data_in_cpu,
data_out => data_out_cpu,
data_w => data_w_cpu,
119,13 → 116,10
stall => stall,
 
stall_cpu => stall_cpu,
busy_cpu => busy_cpu,
irq_vector_cpu => irq_vector_cpu,
irq_cpu => irq_cpu,
irq_ack_cpu => irq_ack_cpu,
inst_addr_cpu => inst_addr_cpu,
inst_in_cpu => inst_in_cpu,
data_addr_cpu => data_addr_cpu,
address_cpu => address_cpu,
data_in_cpu => data_in_cpu,
data_out_cpu => data_out_cpu,
data_w_cpu => data_w_cpu,
135,8 → 129,8
data_read_mem => data_read,
data_write_mem => data_write,
data_we_mem => data_we,
extio_in => ext_irq,
extio_out => open,
extio_in => extio_in,
extio_out => extio_out,
uart_read => uart_read,
uart_write => uart_write
);
202,5 → 196,5
end if;
end process;
 
end interface;
end top_level;
 
/platform/spartan3e_nexys2/spartan3e_nexys2.vhd
2,7 → 2,7
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity hellfire_cpu_if is
entity hfrisc_soc is
generic(
address_width: integer := 14;
memory_file : string := "code.txt";
14,11 → 14,11
uart_read: in std_logic;
uart_write: 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, 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_n_ram, data_w_cpu: std_logic_vector(3 downto 0);
begin
69,13 → 69,10
port map( clock => clock,
reset => reset,
stall => stall_cpu,
busy => busy_cpu,
irq_vector => irq_vector_cpu,
irq => irq_cpu,
irq_ack => irq_ack_cpu,
inst_addr => inst_addr_cpu,
inst_in => inst_in_cpu,
data_addr => data_addr_cpu,
address => address_cpu,
data_in => data_in_cpu,
data_out => data_out_cpu,
data_w => data_w_cpu,
94,13 → 91,10
stall => stall,
 
stall_cpu => stall_cpu,
busy_cpu => busy_cpu,
irq_vector_cpu => irq_vector_cpu,
irq_cpu => irq_cpu,
irq_ack_cpu => irq_ack_cpu,
inst_addr_cpu => inst_addr_cpu,
inst_in_cpu => inst_in_cpu,
data_addr_cpu => data_addr_cpu,
address_cpu => address_cpu,
data_in_cpu => data_in_cpu,
data_out_cpu => data_out_cpu,
data_w_cpu => data_w_cpu,
185,5 → 179,5
data_o => data_read_ram(31 downto 24)
);
 
end interface;
end top_level;
 
/platform/spartan3e_nexys2/spartan3e_nexys2_xtea.vhd
2,7 → 2,7
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity hellfire_cpu_if is
entity hfrisc_soc is
generic(
address_width: integer := 14;
memory_file : string := "code.txt";
14,11 → 14,11
uart_read: in std_logic;
uart_write: 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, 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_n_ram, data_w_cpu: std_logic_vector(3 downto 0);
 
68,33 → 68,39
 
 
 
process (data_addr_cpu, key, input, output)
process (clock, reset, address_cpu, key, input, output)
begin
case data_addr_cpu(7 downto 4) is
when "0000" => -- control 0xfa000000 (bit2 - ready (R), bit1 - encrypt (RW), bit0 - start (RW)
data_read_xtea <= x"000000" & "00000" & ready & control;
when "0001" => -- key[0] 0xfa000010
data_read_xtea <= key(127 downto 96);
when "0010" => -- key[1] 0xfa000020
data_read_xtea <= key(95 downto 64);
when "0011" => -- key[2] 0xfa000030
data_read_xtea <= key(63 downto 32);
when "0100" => -- key[3] 0xfa000040
data_read_xtea <= key(31 downto 0);
when "0101" => -- input[0] 0xfa000050
data_read_xtea <= input(63 downto 32);
when "0110" => -- input[1] 0xfa000060
data_read_xtea <= input(31 downto 0);
when "0111" => -- output[0] 0xfa000070
data_read_xtea <= output(63 downto 32);
when "1000" => -- output[1] 0xfa000080
data_read_xtea <= output(31 downto 0);
when others =>
data_read_xtea <= (others => '0');
end case;
if reset = '1' then
data_read_xtea <= (others => '0');
elsif clock'event and clock = '1' then
if (ext_periph = '1') then -- XTEA is at 0xfa000000
case address_cpu(7 downto 4) is
when "0000" => -- control 0xfa000000 (bit2 - ready (R), bit1 - encrypt (RW), bit0 - start (RW)
data_read_xtea <= x"000000" & "00000" & ready & control;
when "0001" => -- key[0] 0xfa000010
data_read_xtea <= key(127 downto 96);
when "0010" => -- key[1] 0xfa000020
data_read_xtea <= key(95 downto 64);
when "0011" => -- key[2] 0xfa000030
data_read_xtea <= key(63 downto 32);
when "0100" => -- key[3] 0xfa000040
data_read_xtea <= key(31 downto 0);
when "0101" => -- input[0] 0xfa000050
data_read_xtea <= input(63 downto 32);
when "0110" => -- input[1] 0xfa000060
data_read_xtea <= input(31 downto 0);
when "0111" => -- output[0] 0xfa000070
data_read_xtea <= output(63 downto 32);
when "1000" => -- output[1] 0xfa000080
data_read_xtea <= output(31 downto 0);
when others =>
data_read_xtea <= (others => '0');
end case;
end if;
end if;
end process;
 
process (clock, reset, data_addr_cpu, control, key, input, output)
process (clock, reset, address_cpu, control, key, input, output)
begin
if reset = '1' then
key <= (others => '0');
102,7 → 108,7
control <= "00";
elsif clock'event and clock = '1' then
if (ext_periph = '1' and data_we /= "0000") then -- XTEA is at 0xfa000000
case data_addr_cpu(7 downto 4) is
case address_cpu(7 downto 4) is
when "0000" => -- control 0xfa000000 (bit2 - ready (R), bit1 - encrypt (RW), bit0 - start (RW)
control <= data_write(1 downto 0);
when "0001" => -- key[0] 0xfa000010
123,8 → 129,6
end if;
end process;
 
 
 
stall <= '0';
boot_enable <= '1' when address(31 downto 28) = "0000" else '0';
ram_enable_n <= '0' when address(31 downto 28) = "0100" else '1';
137,13 → 141,10
port map( clock => clock,
reset => reset,
stall => stall_cpu,
busy => busy_cpu,
irq_vector => irq_vector_cpu,
irq => irq_cpu,
irq_ack => irq_ack_cpu,
inst_addr => inst_addr_cpu,
inst_in => inst_in_cpu,
data_addr => data_addr_cpu,
address => address_cpu,
data_in => data_in_cpu,
data_out => data_out_cpu,
data_w => data_w_cpu,
162,13 → 163,10
stall => stall,
 
stall_cpu => stall_cpu,
busy_cpu => busy_cpu,
irq_vector_cpu => irq_vector_cpu,
irq_cpu => irq_cpu,
irq_ack_cpu => irq_ack_cpu,
inst_addr_cpu => inst_addr_cpu,
inst_in_cpu => inst_in_cpu,
data_addr_cpu => data_addr_cpu,
address_cpu => address_cpu,
data_in_cpu => data_in_cpu,
data_out_cpu => data_out_cpu,
data_w_cpu => data_w_cpu,
265,5 → 263,5
data_o => data_read_ram(31 downto 24)
);
 
end interface;
end top_level;
 
/platform/virtex4_ml403/virtex4ml403.vhd
2,7 → 2,7
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity hellfire_cpu_if is
entity hfrisc_soc is
generic(
address_width: integer := 16;
memory_file : string := "code.txt";
13,16 → 13,14
uart_read: in std_logic;
uart_write: out std_logic
);
end hellfire_cpu_if;
end hfrisc_soc;
 
architecture interface of hellfire_cpu_if is
signal clock, reset, boot_enable, ram_enable_n, stall, stall_cpu, busy_cpu, irq_cpu, irq_ack_cpu, data_access_cpu, ram_dly: 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);
architecture top_level of hfrisc_soc is
signal clock, reset, boot_enable, ram_enable_n, stall, stall_cpu, irq_cpu, irq_ack_cpu, data_access_cpu, rff1, ram_dly: std_logic;
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_n_ram, data_w_cpu: std_logic_vector(3 downto 0);
begin
reset <= not reset_in;
 
-- clock divider (50MHz clock from 100MHz main clock for ML403 kit)
process (reset, clk_in, clock)
begin
69,13 → 67,10
port map( clock => clock,
reset => reset,
stall => stall_cpu,
busy => busy_cpu,
irq_vector => irq_vector_cpu,
irq => irq_cpu,
irq_ack => irq_ack_cpu,
inst_addr => inst_addr_cpu,
inst_in => inst_in_cpu,
data_addr => data_addr_cpu,
address => address_cpu,
data_in => data_in_cpu,
data_out => data_out_cpu,
data_w => data_w_cpu,
94,13 → 89,10
stall => stall,
 
stall_cpu => stall_cpu,
busy_cpu => busy_cpu,
irq_vector_cpu => irq_vector_cpu,
irq_cpu => irq_cpu,
irq_ack_cpu => irq_ack_cpu,
inst_addr_cpu => inst_addr_cpu,
inst_in_cpu => inst_in_cpu,
data_addr_cpu => data_addr_cpu,
address_cpu => address_cpu,
data_in_cpu => data_in_cpu,
data_out_cpu => data_out_cpu,
data_w_cpu => data_w_cpu,
185,5 → 177,5
data_o => data_read_ram(31 downto 24)
);
 
end interface;
end top_level;
 
/sim/hf-risc_tb.vhd
10,15 → 10,15
address_width: integer := 16;
memory_file : string := "code.txt";
log_file: string := "out.txt";
uart_support : string := "yes"
uart_support : string := "no"
);
end tb;
 
architecture tb of tb is
signal clock_in, reset, busy_cpu, stall_cpu, data, stall, stall_sig: std_logic := '0';
signal clock_in, reset, stall_cpu, data, stall, stall_sig: std_logic := '0';
signal uart_read, uart_write: std_logic;
signal boot_enable_n, ram_enable_n, irq_cpu, irq_ack_cpu, data_access_cpu, ram_dly: 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_n_ram, data_w_cpu: std_logic_vector(3 downto 0);
begin
62,13 → 62,10
port map( clock => clock_in,
reset => reset,
stall => stall_cpu,
busy => busy_cpu,
irq_vector => irq_vector_cpu,
irq => irq_cpu,
irq_ack => irq_ack_cpu,
inst_addr => inst_addr_cpu,
inst_in => inst_in_cpu,
data_addr => data_addr_cpu,
address => address_cpu,
data_in => data_in_cpu,
data_out => data_out_cpu,
data_w => data_w_cpu,
88,13 → 85,10
stall => stall_sig,
 
stall_cpu => stall_cpu,
busy_cpu => busy_cpu,
irq_vector_cpu => irq_vector_cpu,
irq_cpu => irq_cpu,
irq_ack_cpu => irq_ack_cpu,
inst_addr_cpu => inst_addr_cpu,
inst_in_cpu => inst_in_cpu,
data_addr_cpu => data_addr_cpu,
address_cpu => address_cpu,
data_in_cpu => data_in_cpu,
data_out_cpu => data_out_cpu,
data_w_cpu => data_w_cpu,
227,7 → 221,7
-- debug process
debug:
if uart_support = "no" generate
process(clock_in, data_addr_cpu)
process(clock_in, address_cpu)
file store_file : text open write_mode is "debug.txt";
variable hex_file_line : line;
variable c : character;
235,7 → 229,7
variable line_length : natural := 0;
begin
if clock_in'event and clock_in = '1' then
if data_addr_cpu = x"f00000d0" and data = '0' then
if address_cpu = x"f00000d0" and data = '0' then
data <= '1';
index := conv_integer(data_write(6 downto 0));
if index /= 10 then
/ucore/datapath.vhd
8,16 → 8,12
reset: in std_logic;
 
stall: in std_logic;
busy: in std_logic;
 
irq_vector: in std_logic_vector(31 downto 0);
irq: in std_logic;
irq_ack: out std_logic;
 
inst_addr: out std_logic_vector(31 downto 0);
inst_in: in std_logic_vector(31 downto 0);
 
data_addr: out std_logic_vector(31 downto 0);
address: out std_logic_vector(31 downto 0);
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0);
data_w: out std_logic_vector(3 downto 0);
32,8 → 28,8
signal read_reg1, read_reg2, write_reg, rs, rt, rd, target: std_logic_vector(4 downto 0);
signal write_data, read_data1, read_data2: std_logic_vector(31 downto 0);
signal imm: std_logic_vector(15 downto 0);
signal wreg, zero, less_than, br_link_ctl, branch_taken, jump_taken, stall_reg: std_logic;
signal irq_ack_s, irq_ack_s_dly, bds: std_logic;
signal wreg, zero, less_than, br_link_ctl, branch_taken, jump_taken, mwait, stall_reg: std_logic;
signal irq_ack_s, irq_ack_s_dly, bds, data_access_s, data_access_s_dly: std_logic;
 
-- control signals
signal reg_dst_ctl, reg_write_ctl, alu_src_ctl, reg_to_mem_ctl, mem_to_reg_ctl, mem_to_reg_ctl_dly, signed_imm_ctl, signed_rd_ctl, shift_ctl: std_logic;
56,7 → 52,7
-- 1st stage, instruction memory access, PC update, interrupt acknowledge logic
 
-- program counter logic
process(clock, reset, reg_to_mem_ctl_r, mem_to_reg_ctl_r, busy, stall)
process(clock, reset, reg_to_mem_ctl_r, mem_to_reg_ctl_r, mwait, stall)
begin
if reset = '1' then
pc <= (others => '0');
63,7 → 59,7
pc_last <= (others => '0');
elsif clock'event and clock = '1' then
if stall = '0' then
if busy = '0' then
if mwait = '0' then
pc <= pc_next;
pc_last <= pc;
else
89,7 → 85,7
 
irq_ack <= irq_ack_s_dly;
 
process(clock, reset, irq, irq_ack_s, mem_to_reg_ctl_r, busy, stall)
process(clock, reset, irq, irq_ack_s, mem_to_reg_ctl_r, mwait, stall)
begin
if reset = '1' then
irq_ack_s_dly <= '0';
96,11 → 92,13
bds <= '0';
mem_to_reg_ctl_dly <= '0';
stall_reg <= '0';
data_access_s_dly <= '0';
elsif clock'event and clock = '1' then
stall_reg <= stall;
if stall = '0' then
mem_to_reg_ctl_dly <= mem_to_reg_ctl_r;
if busy = '0' then
data_access_s_dly <= data_access_s;
if mwait = '0' then
irq_ack_s_dly <= irq_ack_s;
if branch_taken = '1' or jump_taken = '1' then
bds <= '1';
118,15 → 116,15
-- 2nd stage, instruction decode, control unit operation, pipeline bubble insertion logic on load/store and 2nd branch delay slot
 
-- instruction decode
opcode <= inst_in(31 downto 26);
rs <= inst_in(25 downto 21);
rt <= inst_in(20 downto 16);
rd <= "11111" when br_link_ctl = '1' else inst_in(15 downto 11); -- FIXME: this will not work for the 'jalr rd, rs' format
funct <= inst_in(5 downto 0);
imm <= inst_in(15 downto 0);
opcode <= data_in(31 downto 26);
rs <= data_in(25 downto 21);
rt <= data_in(20 downto 16);
rd <= "11111" when br_link_ctl = '1' else data_in(15 downto 11); -- FIXME: this will not work for the 'jalr rd, rs' format
funct <= data_in(5 downto 0);
imm <= data_in(15 downto 0);
 
-- control unit
control_hellfire: entity work.control
control_unit: entity work.control
port map( opcode => opcode,
funct => funct,
rtx => rt,
146,7 → 144,7
shift => shift_ctl
);
 
process(clock, reset, busy, stall)
process(clock, reset, mwait, stall)
begin
if reset = '1' then
rs_r <= (others => '0');
189,7 → 187,7
signed_rd_ctl_r <= '0';
shift_ctl_r <= '0';
else
if busy = '0' then
if mwait = '0' then
if reg_to_mem_ctl_r = '1' or mem_to_reg_ctl_r = '1' or bds = '1' then
rs_r <= (others => '0');
rt_r <= (others => '0');
259,7 → 257,7
write_reg <= target when mem_to_reg_ctl_r = '0' else rt_r;
ext32 <= x"0000" & imm_r when (imm_r(15) = '0' or signed_imm_ctl_r = '0') else x"ffff" & imm_r;
target <= rt_r when reg_dst_ctl_r = '0' else rd_r; -- target register selection
wreg <= (reg_write_ctl_r or mem_to_reg_ctl_dly) and not busy and not stall_reg; -- enable the register bank for write back also
wreg <= (reg_write_ctl_r or mem_to_reg_ctl_dly) and not mwait and not stall_reg; -- enable the register bank for write back also
 
-- 3rd stage (b) ALU operation
alu: entity work.alu
285,9 → 283,10
else '0';
jump_taken <= '1' when jump_ctl_r /= "00" else '0'; -- J, JAL, JR, JALR
 
inst_addr <= pc;
data_addr <= result; --result(31 downto 2) & "00";
data_access <= '1' when reg_to_mem_ctl_r = '1' or mem_to_reg_ctl_r = '1' else '0';
address <= result when data_access_s = '1' and mwait = '1' else pc;
data_access_s <= '1' when reg_to_mem_ctl_r = '1' or mem_to_reg_ctl_r = '1' else '0';
mwait <= '1' when data_access_s = '1' and data_access_s_dly = '0' else '0';
data_access <= mwait;
 
 
-- 3rd stage (c) data memory / write back operation, register file access (write)
/ucore/peripherals_busmux.vhd
1,4 → 1,4
-- HF-RISC v3.4
-- HF-RISC v3.5
-- Sergio Johann Filho, 2011 - 2016
--
-- *This is a quick and dirty organization of a 3-stage pipelined MIPS microprocessor. All registers / memory
20,8 → 20,8
-- *Memory is accessed in big endian mode.
-- *No unaligned loads/stores.
-- *No co-processor is implemented and all peripherals are memory mapped.
-- *Loads and stores take 2/1 cycles with separated code/data memories and 3 cycles otherwise. This version is organized
-- as a Von Neumann machine, so there is only one memory interface that is shared betweeen code and data accesses.
-- *Loads and stores take 3 cycles. This version is organized as a Von Neumann machine, so there is only one
-- memory interface that is shared betweeen code and data accesses.
-- No load delay slots are needed in code.
-- *Branches have a 1 cycle delay (not taken) or 3 cycle dalay (taken), including two branch delay slots.
-- This is a side effect of the pipeline refill and memory access policy. All other instructions are single
123,13 → 123,10
stall: in std_logic;
 
stall_cpu: out std_logic;
busy_cpu: out std_logic;
irq_vector_cpu: out std_logic_vector(31 downto 0);
irq_cpu: out std_logic;
irq_ack_cpu: in std_logic;
inst_addr_cpu: in std_logic_vector(31 downto 0);
inst_in_cpu: out std_logic_vector(31 downto 0);
data_addr_cpu: in std_logic_vector(31 downto 0);
address_cpu: in std_logic_vector(31 downto 0);
data_in_cpu: out std_logic_vector(31 downto 0);
data_out_cpu: in std_logic_vector(31 downto 0);
data_w_cpu: in std_logic_vector(3 downto 0);
151,7 → 148,7
signal write_enable: std_logic;
signal irq_cause, irq_mask_reg, uart_divisor: std_logic_vector(15 downto 0);
signal irq_status_reg, extio_out_reg: std_logic_vector(7 downto 0);
signal irq_vector_reg, irq_epc_reg, compare_reg, counter_reg: std_logic_vector(31 downto 0);
signal periph_data, irq_vector_reg, irq_epc_reg, compare_reg, counter_reg: std_logic_vector(31 downto 0);
signal compare2_reg: std_logic_vector(23 downto 0);
signal interrupt, irq, irq_counter, irq_counter_not, irq_counter2, irq_counter2_not, irq_compare, irq_compare2, compare_trig, compare2_trig: std_logic;
signal data_read_uart, data_write_uart: std_logic_vector(7 downto 0);
161,52 → 158,53
signal pulse_state: pulse_state_type;
signal pulse_next_state: pulse_state_type;
 
signal periph_access, periph_access_we, data_access_cpu_dly, data_access_cpu_dly2: std_logic;
signal periph_access, periph_access_dly, periph_access_we: std_logic;
signal data_we_mem_s: std_logic_vector(3 downto 0);
 
begin
-- address decoder, read from peripheral registers
process(data_addr_cpu, irq_vector_reg, irq_cause, irq_mask_reg, irq_status_reg, irq_epc_reg, compare_reg, compare2_reg, counter_reg, data_read_uart, uart_divisor, data_read_mem, extio_in, extio_out_reg)
-- peripheral register logic, read from peripheral registers
process(clock, reset, periph_access, address_cpu, irq_vector_reg, irq_cause, irq_mask_reg, irq_status_reg, irq_epc_reg, compare_reg, compare2_reg, counter_reg, data_read_uart, uart_divisor, data_read_mem, extio_in, extio_out_reg)
begin
case data_addr_cpu(31 downto 27) is
when "11110" => -- Peripherals (f000 0000 - f7ff ffff)
case data_addr_cpu(7 downto 4) is
if reset = '1' then
periph_data <= (others => '0');
elsif clock'event and clock = '1' then
if periph_access = '1' then
case address_cpu(7 downto 4) is
when "0000" => -- IRQ_VECTOR (RW)
data_in_cpu <= irq_vector_reg;
periph_data <= irq_vector_reg;
when "0001" => -- IRQ_CAUSE (RO)
data_in_cpu <= x"0000" & irq_cause;
periph_data <= x"0000" & irq_cause;
when "0010" => -- IRQ_MASK (RW)
data_in_cpu <= x"0000" & irq_mask_reg;
periph_data <= x"0000" & irq_mask_reg;
when "0011" => -- IRQ_STATUS (RW)
data_in_cpu <= x"000000" & irq_status_reg;
periph_data <= x"000000" & irq_status_reg;
when "0100" => -- IRQ_EPC (RO)
data_in_cpu <= irq_epc_reg;
periph_data <= irq_epc_reg;
when "0101" => -- COUNTER (RO)
data_in_cpu <= counter_reg;
periph_data <= counter_reg;
when "0110" => -- IRQ_COMPARE (RW)
data_in_cpu <= compare_reg;
periph_data <= compare_reg;
when "0111" => -- IRQ_COMPARE2 (RW)
data_in_cpu <= x"00" & compare2_reg;
periph_data <= x"00" & compare2_reg;
when "1000" => -- EXTIO_IN (RO)
data_in_cpu <= x"000000" & extio_in;
periph_data <= x"000000" & extio_in;
when "1001" => -- EXTIO_OUT (RW)
data_in_cpu <= x"000000" & extio_out_reg;
periph_data <= x"000000" & extio_out_reg;
when "1110" => -- UART (RW)
data_in_cpu <= x"000000" & data_read_uart;
periph_data <= x"000000" & data_read_uart;
when "1111" => -- UART_DIVISOR (RW)
data_in_cpu <= x"0000" & uart_divisor;
periph_data <= x"0000" & uart_divisor;
when others =>
data_in_cpu <= data_read_mem;
periph_data <= data_read_mem;
end case;
when others => -- ROM / RAM area, external peripherals (f800 0000 - ffff fffc)
data_in_cpu <= data_read_mem;
end case;
end if;
end if;
end process;
 
inst_in_cpu <= data_read_mem;
data_in_cpu <= data_read_mem when periph_access_dly = '0' else periph_data;
 
-- peripheral register logic, write to peripheral registers
process(clock, reset, counter_reg, data_addr_cpu, data_out_cpu, periph_access, periph_access_we, irq_ack_cpu)
process(clock, reset, counter_reg, address_cpu, data_out_cpu, periph_access, periph_access_we, irq_ack_cpu)
begin
if reset = '1' then
irq_vector_reg <= x"00000000";
228,7 → 226,7
compare2_trig <= '1';
end if;
if periph_access = '1' and periph_access_we = '1' then
case data_addr_cpu(7 downto 4) is
case address_cpu(7 downto 4) is
when "0000" => -- IRQ_VECTOR
irq_vector_reg <= data_out_cpu;
when "0010" => -- IRQ_MASK
255,13 → 253,13
end process;
 
-- EPC register register load on interrupts
process(clock, reset, inst_addr_cpu, irq)
process(clock, reset, address_cpu, irq)
begin
if reset = '1' then
irq_epc_reg <= x"00000000";
elsif clock'event and clock = '1' then
if irq = '1' and irq_ack_cpu = '0' then
irq_epc_reg <= inst_addr_cpu;
irq_epc_reg <= address_cpu;
end if;
end if;
end process;
303,33 → 301,26
end process;
 
-- data / peripheral access delay
process(clock, reset, irq_ack_cpu, data_access_cpu, stall)
process(clock, reset, irq_ack_cpu, periph_access, stall)
begin
if reset = '1' then
data_access_cpu_dly <= '0';
data_access_cpu_dly2 <= '0';
periph_access_dly <= '0';
elsif clock'event and clock = '1' then
if stall = '0' then
data_access_cpu_dly2 <= data_access_cpu_dly;
if data_access_cpu = '1' and data_access_cpu_dly = '0' and data_access_cpu_dly2 = '0' then
data_access_cpu_dly <= '1';
else
data_access_cpu_dly <= '0';
end if;
periph_access_dly <= periph_access;
end if;
end if;
end process;
 
periph_access <= '1' when data_addr_cpu(31 downto 27) = "11110" and data_access_cpu = '1' else '0';
periph_access <= '1' when address_cpu(31 downto 27) = "11110" and data_access_cpu = '1' else '0';
periph_access_we <= '1' when periph_access <= '1' and data_w_cpu /= "0000" else '0';
 
-- memory address / write enable muxes and cpu stall logic
addr_mem <= data_addr_cpu when data_access_cpu_dly = '0' and data_access_cpu = '1' and periph_access = '0' else inst_addr_cpu;
addr_mem <= address_cpu;
data_write_mem <= data_out_cpu;
data_we_mem_s <= data_w_cpu when data_access_cpu_dly = '0' and data_access_cpu = '1' and periph_access = '0' else "0000";
data_we_mem_s <= data_w_cpu when data_access_cpu = '1' and periph_access = '0' else "0000";
data_we_mem <= data_we_mem_s;
 
busy_cpu <= (data_access_cpu and not data_access_cpu_dly); -- load/store: 1 wait cycle
stall_cpu <= stall;
 
-- interrupts and peripherals
351,7 → 342,7
 
uart:
if uart_support = "yes" generate
enable_uart <= '1' when periph_access = '1' and data_addr_cpu(7 downto 4) = "1110" else '0';
enable_uart <= '1' when periph_access = '1' and address_cpu(7 downto 4) = "1110" else '0';
enable_uart_write <= enable_uart and periph_access_we;
enable_uart_read <= enable_uart and not periph_access_we;
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.