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/ucore
    from Rev 17 to Rev 18
    Reverse comparison

Rev 17 → Rev 18

/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)
/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.