Line 1... |
Line 1... |
-- HF-RISCV v1.2
|
-- HF-RISCV v1.3
|
-- Sergio Johann Filho, 2015 - 2016
|
-- Sergio Johann Filho, 2015 - 2016
|
--
|
--
|
-- *This is a quick and dirty organization of a 3-stage pipelined RISC-V microprocessor. All registers / memory
|
-- *This is a quick and dirty organization of a 3-stage pipelined RISC-V microprocessor. All registers / memory
|
-- accesses are synchronized to the rising edge of clock. The same processor could be designed with only 2
|
-- accesses are synchronized to the rising edge of clock. The same processor could be designed with only 2
|
-- pipeline stages, but this would require memories to be either asynchronous (as presented on comp arq text
|
-- pipeline stages, but this would require memories to be either asynchronous (as presented on comp arq text
|
Line 132... |
Line 132... |
signal compare2_reg: std_logic_vector(23 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 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);
|
signal data_read_uart, data_write_uart: std_logic_vector(7 downto 0);
|
signal enable_uart, enable_uart_read, enable_uart_write, uart_write_busy, uart_data_avail: std_logic;
|
signal enable_uart, enable_uart_read, enable_uart_write, uart_write_busy, uart_data_avail: std_logic;
|
|
|
type pulse_state_type is (irq_idle, irq_intdly1, irq_intdly2, irq_int, irq_req, irq_ackn, irq_done);
|
type pulse_state_type is (irq_idle, irq_int, irq_req, irq_ackn, irq_done);
|
signal pulse_state: pulse_state_type;
|
signal pulse_state: pulse_state_type;
|
signal pulse_next_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_we, data_access_cpu_dly, data_access_cpu_dly2: std_logic;
|
signal data_we_mem_s: std_logic_vector(3 downto 0);
|
signal data_we_mem_s: std_logic_vector(3 downto 0);
|
Line 202... |
Line 202... |
compare_trig <= '1';
|
compare_trig <= '1';
|
end if;
|
end if;
|
if compare2_reg = counter_reg(23 downto 0) then
|
if compare2_reg = counter_reg(23 downto 0) then
|
compare2_trig <= '1';
|
compare2_trig <= '1';
|
end if;
|
end if;
|
if irq = '0' and exception_cpu = '0' then
|
|
if periph_access = '1' and periph_access_we = '1' then
|
if periph_access = '1' and periph_access_we = '1' then
|
case data_addr_cpu(7 downto 4) is
|
case data_addr_cpu(7 downto 4) is
|
when "0000" => -- IRQ_VECTOR
|
when "0000" => -- IRQ_VECTOR
|
irq_vector_reg <= data_out_cpu(7 downto 0) & data_out_cpu(15 downto 8) & data_out_cpu(23 downto 16) & data_out_cpu(31 downto 24);
|
irq_vector_reg <= data_out_cpu(7 downto 0) & data_out_cpu(15 downto 8) & data_out_cpu(23 downto 16) & data_out_cpu(31 downto 24);
|
when "0010" => -- IRQ_MASK
|
when "0010" => -- IRQ_MASK
|
Line 224... |
Line 223... |
when "1111" => -- UART_DIVISOR
|
when "1111" => -- UART_DIVISOR
|
uart_divisor <= data_out_cpu(23 downto 16) & data_out_cpu(31 downto 24);
|
uart_divisor <= data_out_cpu(23 downto 16) & data_out_cpu(31 downto 24);
|
when others =>
|
when others =>
|
end case;
|
end case;
|
end if;
|
end if;
|
else
|
if irq_ack_cpu = '1' or exception_cpu = '1' then
|
irq_status_reg(0) <= '0'; -- IRQ_STATUS (clear master int bit on interrupt)
|
irq_status_reg(0) <= '0'; -- IRQ_STATUS (clear master int bit on interrupt)
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 254... |
Line 253... |
elsif clock'event and clock = '1' then
|
elsif clock'event and clock = '1' then
|
if stall = '0' then
|
if stall = '0' then
|
pulse_state <= pulse_next_state;
|
pulse_state <= pulse_next_state;
|
case pulse_state is
|
case pulse_state is
|
when irq_idle =>
|
when irq_idle =>
|
if interrupt = '1' then
|
if interrupt = '1' and irq_status_reg(0) = '1' then
|
pulse_next_state <= irq_intdly1;
|
|
end if;
|
|
when irq_intdly1 =>
|
|
if irq_status_reg(0) = '1' then
|
|
pulse_next_state <= irq_intdly2;
|
|
end if;
|
|
when irq_intdly2 =>
|
|
pulse_next_state <= irq_int;
|
pulse_next_state <= irq_int;
|
|
end if;
|
when irq_int =>
|
when irq_int =>
|
irq <= '1';
|
irq <= '1';
|
pulse_next_state <= irq_req;
|
pulse_next_state <= irq_req;
|
when irq_req =>
|
when irq_req =>
|
if irq_ack_cpu = '1' then
|
if irq_ack_cpu = '1' then
|