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; |
|