OpenCores
URL https://opencores.org/ocsvn/potato/potato/trunk

Subversion Repositories potato

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /potato/branches
    from Rev 52 to Rev 53
    Reverse comparison

Rev 52 → Rev 53

/new-privileged-isa/src/pp_execute.vhd
17,8 → 17,9
 
stall, flush : in std_logic;
 
-- IRQ input:
-- Interrupt inputs:
irq : in std_logic_vector(7 downto 0);
software_interrupt, timer_interrupt : in std_logic;
 
-- Data memory outputs:
dmem_address : out std_logic_vector(31 downto 0);
77,9 → 78,11
count_instruction_out : out std_logic;
 
-- Exception control registers:
status_in : in csr_status_register;
evec_in : in std_logic_vector(31 downto 0);
evec_out : out std_logic_vector(31 downto 0);
ie_in, ie1_in : in std_logic;
mie_in : in std_logic_vector(31 downto 0);
mtvec_in : in std_logic_vector(31 downto 0);
mtvec_out : out std_logic_vector(31 downto 0);
--mepc_in : in std_logic_vector(31 downto 0);
 
-- Exception signals:
decode_exception_in : in std_logic;
143,8 → 146,8
signal do_jump : std_logic;
signal jump_target : std_logic_vector(31 downto 0);
 
signal sr : csr_status_register;
signal evec, evec_forwarded : std_logic_vector(31 downto 0);
signal mtvec, mtvec_forwarded : std_logic_vector(31 downto 0);
signal mie, mie_forwarded : std_logic_vector(31 downto 0);
 
signal csr_write : csr_write_mode;
signal csr_addr : csr_address;
158,7 → 161,7
 
signal exception_taken : std_logic;
signal exception_cause : csr_exception_cause;
signal exception_vaddr : std_logic_vector(31 downto 0);
signal exception_addr : std_logic_vector(31 downto 0);
 
signal exception_context_forwarded : csr_exception_context;
 
185,9 → 188,10
 
exception_out <= exception_taken;
exception_context_out <= (
status => exception_context_forwarded.status,
ie => exception_context_forwarded.ie,
ie1 => exception_context_forwarded.ie1,
cause => exception_cause,
badvaddr => exception_vaddr
badaddr => exception_addr
) when exception_taken = '1' else exception_context_forwarded;
 
do_jump <= (to_std_logic(branch = BRANCH_JUMP or branch = BRANCH_JUMP_INDIRECT)
196,19 → 200,19
jump_out <= do_jump;
jump_target_out <= jump_target;
 
evec_out <= evec_forwarded;
exception_taken <= (decode_exception or to_std_logic(exception_cause /= CSR_CAUSE_NONE) or irq_asserted) and not stall;
mtvec_out <= std_logic_vector(unsigned(mtvec_forwarded) + CSR_MTVEC_M_OFFSET);
exception_taken <= not stall and (decode_exception or to_std_logic(exception_cause /= CSR_CAUSE_NONE));
 
irq_asserted <= to_std_logic(exception_context_forwarded.status.ei = '1' and
(irq and exception_context_forwarded.status.im) /= x"00");
irq_asserted <= to_std_logic(exception_context_forwarded.ie = '1' and (irq and mie_forwarded(31 downto 24)) /= x"00");
 
rs1_data <= rs1_data_in;
rs2_data <= rs2_data_in;
 
dmem_address <= alu_result;
dmem_address <= alu_result when (mem_op /= MEMOP_TYPE_NONE and mem_op /= MEMOP_TYPE_INVALID) and exception_taken = '0'
else (others => '0');
dmem_data_out <= rs2_forwarded;
dmem_write_req <= '1' when mem_op = MEMOP_TYPE_STORE else '0';
dmem_read_req <= '1' when memop_is_load(mem_op) else '0';
dmem_write_req <= '1' when mem_op = MEMOP_TYPE_STORE and exception_taken = '0' else '0';
dmem_read_req <= '1' when memop_is_load(mem_op) and exception_taken = '0' else '0';
 
pipeline_register: process(clk)
begin
251,11 → 255,9
csr_use_immediate <= csr_use_immediate_in;
csr_writeable <= csr_writeable_in;
 
-- Status register;
sr <= status_in;
 
-- Exception vector base:
evec <= evec_in;
mtvec <= mtvec_in;
mie <= mie_in;
 
-- Instruction decoder exceptions:
decode_exception <= decode_exception_in;
278,13 → 280,13
end case;
end process set_data_size;
 
get_irq_num: process(irq, exception_context_forwarded)
get_irq_num: process(irq, exception_context_forwarded, mie_forwarded)
variable temp : std_logic_vector(3 downto 0);
begin
temp := (others => '0');
 
for i in 0 to 7 loop
if irq(i) = '1' and exception_context_forwarded.status.im(i) = '1' then
if irq(i) = '1' and mie_forwarded(24 + i) = '1' then
temp := std_logic_vector(to_unsigned(i, temp'length));
exit;
end if;
323,10 → 325,15
end process instr_misalign_check;
 
find_exception_cause: process(decode_exception, decode_exception_cause, mem_op,
data_misaligned, instr_misaligned, irq_asserted, irq_asserted_num)
data_misaligned, instr_misaligned, irq_asserted, irq_asserted_num, mie_forwarded,
software_interrupt, timer_interrupt, exception_context_forwarded)
begin
if irq_asserted = '1' then
exception_cause <= std_logic_vector(unsigned(CSR_CAUSE_IRQ_BASE) + unsigned(irq_asserted_num));
elsif software_interrupt = '1' and mie_forwarded(CSR_MIE_MSIE) = '1' and exception_context_forwarded.ie = '1' then
exception_cause <= CSR_CAUSE_SOFTWARE_INT;
elsif timer_interrupt = '1' and mie_forwarded(CSR_MIE_MTIE) = '1' and exception_context_forwarded.ie = '1' then
exception_cause <= CSR_CAUSE_TIMER_INT;
elsif decode_exception = '1' then
exception_cause <= decode_exception_cause;
elsif mem_op = MEMOP_TYPE_INVALID then
342,16 → 349,16
end if;
end process find_exception_cause;
 
find_exception_vaddr: process(instr_misaligned, data_misaligned, jump_target, alu_result)
find_exception_addr: process(instr_misaligned, data_misaligned, jump_target, alu_result)
begin
if instr_misaligned = '1' then
exception_vaddr <= jump_target;
exception_addr <= jump_target;
elsif data_misaligned = '1' then
exception_vaddr <= alu_result;
exception_addr <= alu_result;
else
exception_vaddr <= (others => '0');
exception_addr <= (others => '0');
end if;
end process find_exception_vaddr;
end process find_exception_addr;
 
calc_jump_tgt: process(branch, pc, rs1_forwarded, immediate, csr_value_forwarded)
begin
361,7 → 368,7
when BRANCH_JUMP_INDIRECT =>
jump_target <= std_logic_vector(unsigned(rs1_forwarded) + unsigned(immediate));
when BRANCH_SRET =>
jump_target <= csr_value_forwarded; -- Will be the EPC value in the case of SRET
jump_target <= csr_value_forwarded;
when others =>
jump_target <= (others => '0');
end case;
417,20 → 424,20
csr_value, mem_csr_value, wb_csr_value, csr_writeable, mem_exception, wb_exception,
mem_exception_context, wb_exception_context)
begin
if csr_addr = CSR_CAUSE and mem_exception = '1' then
if csr_addr = CSR_MCAUSE and mem_exception = '1' then
csr_value_forwarded <= to_std_logic_vector(mem_exception_context.cause);
elsif csr_addr = CSR_STATUS and mem_exception = '1' then
csr_value_forwarded <= to_std_logic_vector(mem_exception_context.status);
elsif csr_addr = CSR_BADVADDR and mem_exception = '1' then
csr_value_forwarded <= mem_exception_context.badvaddr;
elsif csr_addr = CSR_MSTATUS and mem_exception = '1' then
csr_value_forwarded <= csr_make_mstatus(mem_exception_context.ie, mem_exception_context.ie1);
elsif csr_addr = CSR_MBADADDR and mem_exception = '1' then
csr_value_forwarded <= mem_exception_context.badaddr;
elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = csr_addr and csr_writeable then
csr_value_forwarded <= mem_csr_value;
elsif csr_addr = CSR_CAUSE and wb_exception = '1' then
elsif csr_addr = CSR_MCAUSE and wb_exception = '1' then
csr_value_forwarded <= to_std_logic_vector(wb_exception_context.cause);
elsif csr_addr = CSR_STATUS and wb_exception = '1' then
csr_value_forwarded <= to_std_logic_vector(wb_exception_context.status);
elsif csr_addr = CSR_BADVADDR and wb_exception = '1' then
csr_value_forwarded <= wb_exception_context.badvaddr;
elsif csr_addr = CSR_MSTATUS and wb_exception = '1' then
csr_value_forwarded <= csr_make_mstatus(wb_exception_context.ie, wb_exception_context.ie1);
elsif csr_addr = CSR_MBADADDR and wb_exception = '1' then
csr_value_forwarded <= wb_exception_context.badaddr;
elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = csr_addr and csr_writeable then
csr_value_forwarded <= wb_csr_value;
else
438,40 → 445,55
end if;
end process csr_forward;
 
evec_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value,
wb_csr_write, wb_csr_addr, wb_csr_value, evec)
mtvec_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value,
wb_csr_write, wb_csr_addr, wb_csr_value, mtvec)
begin
if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_EVEC then
evec_forwarded <= mem_csr_value;
elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_EVEC then
evec_forwarded <= wb_csr_value;
if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MTVEC then
mtvec_forwarded <= mem_csr_value;
elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MTVEC then
mtvec_forwarded <= wb_csr_value;
else
evec_forwarded <= evec;
mtvec_forwarded <= mtvec;
end if;
end process evec_forward;
end process mtvec_forward;
 
mie_forward: process(mem_csr_write, mem_csr_addr, mem_csr_value,
wb_csr_write, wb_csr_addr, wb_csr_value, mie)
begin
if mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MIE then
mie_forwarded <= mem_csr_value;
elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MIE then
mie_forwarded <= wb_csr_value;
else
mie_forwarded <= mie;
end if;
end process mie_forward;
 
exception_ctx_forward: process(mem_exception, wb_exception, mem_exception_context, wb_exception_context,
exception_cause, exception_vaddr, mem_csr_write, mem_csr_addr, mem_csr_value,
wb_csr_write, wb_csr_addr, wb_csr_value, sr)
exception_cause, exception_addr, mem_csr_write, mem_csr_addr, mem_csr_value,
wb_csr_write, wb_csr_addr, wb_csr_value, ie_in, ie1_in)
begin
if mem_exception = '1' then
exception_context_forwarded <= mem_exception_context;
elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_STATUS then
elsif mem_csr_write /= CSR_WRITE_NONE and mem_csr_addr = CSR_MSTATUS then
exception_context_forwarded <= (
status => to_csr_status_register(mem_csr_value),
cause => mem_exception_context.cause,
badvaddr => mem_exception_context.badvaddr);
ie => mem_csr_value(CSR_SR_IE),
ie1 => mem_csr_value(CSR_SR_IE1),
cause => exception_cause,
badaddr => exception_addr);
elsif wb_exception = '1' then
exception_context_forwarded <= wb_exception_context;
elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_STATUS then
elsif wb_csr_write /= CSR_WRITE_NONE and wb_csr_addr = CSR_MSTATUS then
exception_context_forwarded <= (
status => to_csr_status_register(wb_csr_value),
cause => wb_exception_context.cause,
badvaddr => wb_exception_context.badvaddr);
ie => wb_csr_value(CSR_SR_IE),
ie1 => wb_csr_value(CSR_SR_IE1),
cause => exception_cause,
badaddr => exception_addr);
else
exception_context_forwarded.status <= sr;
exception_context_forwarded.ie <= ie_in;
exception_context_forwarded.ie1 <= ie1_in;
exception_context_forwarded.cause <= exception_cause;
exception_context_forwarded.badvaddr <= exception_vaddr;
exception_context_forwarded.badaddr <= exception_addr;
end if;
end process exception_ctx_forward;
 
/new-privileged-isa/src/pp_potato.vhd
12,7 → 12,7
entity pp_potato is
generic(
PROCESSOR_ID : std_logic_vector(31 downto 0) := x"00000000"; --! Processor ID.
RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000000" --! Address of the first instruction to execute.
RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000200" --! Address of the first instruction to execute.
);
port(
clk : in std_logic;
/new-privileged-isa/src/pp_memory.vhd
84,7 → 84,7
mem_op <= MEMOP_TYPE_NONE;
rd_write_out <= '0';
csr_write_out <= CSR_WRITE_REPLACE;
csr_addr_out <= CSR_EPC;
csr_addr_out <= CSR_MEPC;
csr_data_out <= pc;
count_instr_out <= '0';
else
108,27 → 108,20
exception_out <= exception_in or to_std_logic(branch = BRANCH_SRET);
 
if exception_in = '1' then
exception_context_out.status <= (
pim => exception_context_in.status.im,
im => (others => '0'),
pei => exception_context_in.status.ei,
ei => '0'
);
exception_context_out.ie <= '0';
exception_context_out.ie1 <= exception_context_in.ie;
exception_context_out.cause <= exception_context_in.cause;
exception_context_out.badvaddr <= exception_context_in.badvaddr;
exception_context_out.badaddr <= exception_context_in.badaddr;
elsif branch = BRANCH_SRET then
exception_context_out.status <= (
pim => exception_context_in.status.pim,
im => exception_context_in.status.pim,
pei => exception_context_in.status.pei,
ei => exception_context_in.status.pei
);
exception_context_out.ie <= exception_context_in.ie1;
exception_context_out.ie1 <= exception_context_in.ie;
exception_context_out.cause <= CSR_CAUSE_NONE;
exception_context_out.badvaddr <= (others => '0');
exception_context_out.badaddr <= (others => '0');
else
exception_context_out.status <= exception_context_in.status;
exception_context_out.ie <= exception_context_in.ie;
exception_context_out.ie1 <= exception_context_in.ie1;
exception_context_out.cause <= CSR_CAUSE_NONE;
exception_context_out.badvaddr <= (others => '0');
exception_context_out.badaddr <= (others => '0');
end if;
end if;
end if;
/new-privileged-isa/src/pp_control_unit.vhd
25,7 → 25,7
 
-- Exception signals:
decode_exception : out std_logic;
decode_exception_cause : out std_logic_vector(4 downto 0);
decode_exception_cause : out csr_exception_cause;
 
-- Control register signals:
csr_write : out csr_write_mode;
45,7 → 45,7
 
architecture behaviour of pp_control_unit is
signal exception : std_logic;
signal exception_cause : std_logic_vector(4 downto 0);
signal exception_cause : csr_exception_cause;
signal alu_op_temp : alu_operation;
begin
 
125,13 → 125,13
 
if funct12 = x"000" then
exception <= '1';
exception_cause <= CSR_CAUSE_SYSCALL;
exception_cause <= CSR_CAUSE_ECALL;
branch <= BRANCH_NONE;
elsif funct12 = x"001" then
exception <= '1';
exception_cause <= CSR_CAUSE_BREAKPOINT;
branch <= BRANCH_NONE;
elsif funct12 = x"800" then
elsif funct12 = CSR_EPC_ERET then
exception <= '0';
exception_cause <= CSR_CAUSE_NONE;
branch <= BRANCH_SRET;
/new-privileged-isa/src/pp_decode.vhd
111,8 → 111,8
 
decode_csr_addr: process(immediate_value)
begin
if immediate_value(11 downto 0) = CSR_EPC_SRET then
csr_addr <= CSR_EPC;
if immediate_value(11 downto 0) = CSR_EPC_ERET then
csr_addr <= CSR_MEPC;
else
csr_addr <= immediate_value(11 downto 0);
end if;
/new-privileged-isa/src/pp_csr_unit.vhd
7,6 → 7,7
use ieee.numeric_std.all;
 
use work.pp_csr.all;
use work.pp_utilities.all;
 
entity pp_csr_unit is
generic(
16,6 → 17,9
clk, timer_clk : in std_logic;
reset : in std_logic;
 
-- IRQ signals:
irq : in std_logic_vector(7 downto 0);
 
-- Count retired instruction:
count_instruction : in std_logic;
 
39,35 → 43,58
exception_context : in csr_exception_context;
exception_context_write : in std_logic;
 
-- Interrupts originating from this unit:
software_interrupt_out : out std_logic;
timer_interrupt_out : out std_logic;
 
-- Registers needed for exception handling, always read:
status_out : out csr_status_register;
evec_out : out std_logic_vector(31 downto 0)
mie_out : out std_logic_vector(31 downto 0);
mtvec_out : out std_logic_vector(31 downto 0);
ie_out, ie1_out : out std_logic
);
end entity pp_csr_unit;
 
architecture behaviour of pp_csr_unit is
 
-- Implemented counters:
-- Counters:
signal counter_time : std_logic_vector(63 downto 0);
signal counter_cycle : std_logic_vector(63 downto 0);
signal counter_instret : std_logic_vector(63 downto 0);
 
-- Implemented registers:
signal sup0, sup1 : std_logic_vector(31 downto 0) := (others => '0');
signal epc, evec : std_logic_vector(31 downto 0) := (others => '0');
signal badvaddr : std_logic_vector(31 downto 0) := (others => '0');
signal cause : csr_exception_cause;
-- Machine time counter:
signal counter_mtime : std_logic_vector(31 downto 0);
signal mtime_compare : std_logic_vector(31 downto 0);
 
-- Machine-mode registers:
signal mcause : csr_exception_cause;
signal mbadaddr : std_logic_vector(31 downto 0);
signal mscratch : std_logic_vector(31 downto 0);
signal mepc : std_logic_vector(31 downto 0);
signal mtvec : std_logic_vector(31 downto 0) := x"00000100";
signal mie : std_logic_vector(31 downto 0) := (others => '0');
 
-- Interrupt enable bits:
signal ie, ie1 : std_logic;
 
-- HTIF FROMHOST register:
signal fromhost: std_logic_vector(31 downto 0);
 
-- Status register:
signal status_register : csr_status_register;
-- Interrupt signals:
signal timer_interrupt : std_logic;
signal software_interrupt : std_logic;
 
begin
 
read_writeable <= csr_is_writeable(read_address);
-- Interrupt signals:
software_interrupt_out <= software_interrupt;
timer_interrupt_out <= timer_interrupt;
ie_out <= ie;
ie1_out <= ie1;
mie_out <= mie;
 
-- The two upper bits of the CSR address encodes the accessibility of the CSR:
read_writeable <= read_address(11 downto 10) /= b"11";
 
--! Updates the FROMHOST register when new data is available.
htif_fromhost: process(clk)
begin
86,7 → 113,7
tohost_data <= (others => '0');
tohost_updated <= '0';
else
if write_mode /= CSR_WRITE_NONE and write_address = CSR_TOHOST then
if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTOHOST then
tohost_data <= write_data_in;
tohost_updated <= '1';
else
96,32 → 123,67
end if;
end process htif_tohost;
 
mtime_counter: process(timer_clk, reset)
begin
if reset = '1' then -- Asynchronous reset because timer_clk is slower than clk
counter_mtime <= (others => '0');
elsif rising_edge(timer_clk) then
counter_mtime <= std_logic_vector(unsigned(counter_mtime) + 1);
end if;
end process mtime_counter;
 
mtime_interrupt: process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
timer_interrupt <= '0';
else
if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTIMECMP then
timer_interrupt <= '0';
elsif counter_mtime = mtime_compare then
timer_interrupt <= '1';
end if;
end if;
end if;
end process mtime_interrupt;
 
write: process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
status_register <= CSR_SR_DEFAULT;
software_interrupt <= '0';
mtvec <= x"00000100";
mepc <= x"00000100";
mie <= (others => '0');
ie <= '0';
ie1 <= '0';
else
if exception_context_write = '1' then
status_register <= exception_context.status;
cause <= exception_context.cause;
badvaddr <= exception_context.badvaddr;
ie <= exception_context.ie;
ie1 <= exception_context.ie1;
mcause <= exception_context.cause;
mbadaddr <= exception_context.badaddr;
end if;
 
if write_mode /= CSR_WRITE_NONE then
case write_address is
when CSR_STATUS =>
if exception_context_write = '0' then
status_register <= to_csr_status_register(write_data_in);
end if;
when CSR_EPC =>
epc <= write_data_in;
when CSR_EVEC =>
evec <= write_data_in;
when CSR_SUP0 =>
sup0 <= write_data_in;
when CSR_SUP1 =>
sup1 <= write_data_in;
when CSR_MSTATUS => -- Status register
ie1 <= write_data_in(CSR_SR_IE1);
ie <= write_data_in(CSR_SR_IE);
when CSR_MSCRATCH => -- Scratch register
mscratch <= write_data_in;
when CSR_MEPC => -- Exception return address
mepc <= write_data_in;
--when CSR_MCAUSE => -- Exception cause
-- mcause <= write_data_in(31) & write_data_in(4 downto 0);
when CSR_MTVEC => -- Exception vector address
mtvec <= write_data_in;
when CSR_MTIMECMP => -- Time compare register
mtime_compare <= write_data_in;
when CSR_MIE => -- Interrupt enable register:
mie <= write_data_in;
when CSR_MIP => -- Interrupt pending register:
software_interrupt <= write_data_in(CSR_MIP_MSIP);
when others =>
-- Ignore writes to invalid or read-only registers
end case;
130,21 → 192,14
end if;
end process write;
 
status_out <= exception_context.status when exception_context_write = '1' else status_register;
 
read: process(clk)
begin
if rising_edge(clk) then
--if exception_context_write = '1' then
-- status_out <= exception_context.status;
--else
-- status_out <= status_register;
--end if;
 
if write_mode /= CSR_WRITE_NONE and write_address = CSR_EVEC then
evec_out <= write_data_in;
if write_mode /= CSR_WRITE_NONE and write_address = CSR_MTVEC then
mtvec_out <= write_data_in;
else
evec_out <= evec;
mtvec_out <= mtvec;
end if;
 
if write_mode /= CSR_WRITE_NONE and write_address = read_address then
151,30 → 206,46
read_data_out <= write_data_in;
else
case read_address is
-- Status and control registers:
when CSR_STATUS => -- Status register
read_data_out <= to_std_logic_vector(status_register);
when CSR_HARTID => -- Processor ID
 
-- Machine mode registers:
when CSR_MCPUID => -- CPU features register
read_data_out <= (
8 => '1', -- Set the bit corresponding to I
others => '0');
when CSR_MIMPID => -- Implementation/Implementor ID
read_data_out <= (31 downto 16 => '0') & x"8000";
-- The anonymous source ID, 0x8000 is used until an open-source implementation ID
-- is available for use.
when CSR_MHARTID => -- Hardware thread ID
read_data_out <= PROCESSOR_ID;
when CSR_FROMHOST => -- Fromhost data
when CSR_MFROMHOST => -- Data from a host environment
read_data_out <= fromhost;
when CSR_EPC | CSR_EPC_SRET => -- Exception PC value
read_data_out <= epc;
when CSR_EVEC => -- Exception handler address
read_data_out <= evec;
when CSR_CAUSE => -- Exception cause
read_data_out <= to_std_logic_vector(cause);
when CSR_BADVADDR => -- Load/store address responsible for the exception
read_data_out <= badvaddr;
when CSR_MSTATUS => -- Status register
read_data_out <= csr_make_mstatus(ie, ie1);
when CSR_MSCRATCH => -- Scratch register
read_data_out <= mscratch;
when CSR_MEPC => -- Exception PC value
read_data_out <= mepc;
when CSR_MTVEC => -- Exception vector address
read_data_out <= mtvec;
when CSR_MTDELEG => -- Exception vector delegation register, unsupported
read_data_out <= (others => '0');
when CSR_MIP => -- Interrupt pending
read_data_out <= irq & (CSR_MIP_MTIP => timer_interrupt, CSR_MIP_MSIP => software_interrupt,
23 downto 8 => '0', 6 downto 4 => '0', 2 downto 0 => '0');
when CSR_MIE => -- Interrupt enable register
read_data_out <= mie;
when CSR_MBADADDR => -- Bad memory address
read_data_out <= mbadaddr;
when CSR_MCAUSE => -- Exception cause
read_data_out <= mcause(5) & (30 downto 5 => '0') & mcause(4 downto 0); --to_std_logic_vector(mcause);
-- Supporting registers:
when CSR_SUP0 =>
read_data_out <= sup0;
when CSR_SUP1 =>
read_data_out <= sup1;
-- Timers and counters:
when CSR_MTIME => -- Machine time counter register
read_data_out <= counter_mtime;
when CSR_MTIMECMP => -- Machine time compare register
read_data_out <= mtime_compare;
 
when CSR_TIME =>
read_data_out <= counter_time(31 downto 0);
when CSR_TIMEH =>
/new-privileged-isa/src/pp_csr.vhd
12,8 → 12,9
subtype csr_address is std_logic_vector(11 downto 0);
 
--! Type used for exception cause values.
subtype csr_exception_cause is std_logic_vector(4 downto 0);
subtype csr_exception_cause is std_logic_vector(5 downto 0); -- Upper bit is the interrupt bit
 
--! Converts an exception cause to a std_logic_vector.
function to_std_logic_vector(input : in csr_exception_cause) return std_logic_vector;
 
--! Control/status register write mode:
22,28 → 23,22
);
 
-- Exception cause values:
constant CSR_CAUSE_INSTR_MISALIGN : csr_exception_cause := b"00000";
constant CSR_CAUSE_INSTR_FETCH : csr_exception_cause := b"00001";
constant CSR_CAUSE_INVALID_INSTR : csr_exception_cause := b"00010";
constant CSR_CAUSE_SYSCALL : csr_exception_cause := b"00110";
constant CSR_CAUSE_BREAKPOINT : csr_exception_cause := b"00111";
constant CSR_CAUSE_LOAD_MISALIGN : csr_exception_cause := b"01000";
constant CSR_CAUSE_STORE_MISALIGN : csr_exception_cause := b"01001";
constant CSR_CAUSE_LOAD_ERROR : csr_exception_cause := b"01010";
constant CSR_CAUSE_STORE_ERROR : csr_exception_cause := b"01011";
constant CSR_CAUSE_FROMHOST : csr_exception_cause := b"11110";
constant CSR_CAUSE_NONE : csr_exception_cause := b"11111";
constant CSR_CAUSE_INSTR_MISALIGN : csr_exception_cause := b"000000";
constant CSR_CAUSE_INSTR_FETCH : csr_exception_cause := b"000001";
constant CSR_CAUSE_INVALID_INSTR : csr_exception_cause := b"000010";
constant CSR_CAUSE_BREAKPOINT : csr_exception_cause := b"000011";
constant CSR_CAUSE_LOAD_MISALIGN : csr_exception_cause := b"000100";
constant CSR_CAUSE_LOAD_ERROR : csr_exception_cause := b"000101";
constant CSR_CAUSE_STORE_MISALIGN : csr_exception_cause := b"000110";
constant CSR_CAUSE_STORE_ERROR : csr_exception_cause := b"000111";
constant CSR_CAUSE_ECALL : csr_exception_cause := b"001011";
constant CSR_CAUSE_NONE : csr_exception_cause := b"011111";
 
constant CSR_CAUSE_IRQ_BASE : csr_exception_cause := b"10000";
constant CSR_CAUSE_SOFTWARE_INT : csr_exception_cause := b"100000";
constant CSR_CAUSE_TIMER_INT : csr_exception_cause := b"100001";
constant CSR_CAUSE_IRQ_BASE : csr_exception_cause := b"110000";
 
-- Control register IDs, specified in the immediate of csr* instructions:
constant CSR_STATUS : csr_address := x"50a";
constant CSR_HARTID : csr_address := x"50b";
constant CSR_SUP0 : csr_address := x"500";
constant CSR_SUP1 : csr_address := x"501";
constant CSR_BADVADDR : csr_address := x"503";
constant CSR_TOHOST : csr_address := x"51e";
constant CSR_FROMHOST : csr_address := x"51f";
-- Control register IDs, specified in the immediate field of csr* instructions:
constant CSR_CYCLE : csr_address := x"c00";
constant CSR_CYCLEH : csr_address := x"c80";
constant CSR_TIME : csr_address := x"c01";
50,57 → 45,61
constant CSR_TIMEH : csr_address := x"c81";
constant CSR_INSTRET : csr_address := x"c02";
constant CSR_INSTRETH : csr_address := x"c82";
constant CSR_EPC : csr_address := x"502";
constant CSR_EVEC : csr_address := x"508";
constant CSR_CAUSE : csr_address := x"509";
 
-- Values used as control register IDs in SRET, SCALL and SBREAK:
constant CSR_EPC_SRET : csr_address := x"800";
constant CSR_MCPUID : csr_address := x"f00";
constant CSR_MIMPID : csr_address := x"f01";
constant CSR_MHARTID : csr_address := x"f10";
 
constant CSR_MSTATUS : csr_address := x"300";
constant CSR_MTVEC : csr_address := x"301";
constant CSR_MTDELEG : csr_address := x"302";
constant CSR_MIE : csr_address := x"304";
 
constant CSR_MTIMECMP : csr_address := x"321";
constant CSR_MTIME : csr_address := x"701";
 
constant CSR_MSCRATCH : csr_address := x"340";
constant CSR_MEPC : csr_address := x"341";
constant CSR_MCAUSE : csr_address := x"342";
constant CSR_MBADADDR : csr_address := x"343";
constant CSR_MIP : csr_address := x"344";
 
constant CSR_MTOHOST : csr_address := x"780";
constant CSR_MFROMHOST : csr_address := x"781";
 
-- Values used as control register IDs in ERET:
constant CSR_EPC_ERET : csr_address := x"100";
 
-- Offset into the exception vector for handling machine-mode exceptions:
constant CSR_MTVEC_M_OFFSET : natural := 192;
 
-- Additional CSRs from supervisor mode that aliases machine mode registers
-- in this implementation:
--constant CSR_STVEC : csr_address := x"101";
--constant CSR_SEPC : csr_address := x"141";
 
-- Status register bit indices:
constant CSR_SR_S : natural := 0;
constant CSR_SR_PS : natural := 1;
constant CSR_SR_EI : natural := 2;
constant CSR_SR_PEI : natural := 3;
constant CSR_SR_IE : natural := 0;
constant CSR_SR_IE1 : natural := 3;
 
-- Status register in Potato:
-- * Bit 0, S: Supervisor mode, always 1
-- * Bit 1, PS: Previous supervisor mode bit, always 1
-- * Bit 2, EI: Enable interrupts bit
-- * Bit 3, PEI: Previous enable interrupts bit
-- * Bits 23 downto 16, IM: Interrupt mask
-- * Bits 31 downto 24, PIM: Previous interrupt mask
-- MIE and MIP register bit indices:
constant CSR_MIE_MSIE : natural := 3;
constant CSR_MIE_MTIE : natural := 7;
constant CSR_MIP_MSIP : natural := CSR_MIE_MSIE;
constant CSR_MIP_MTIP : natural := CSR_MIE_MTIE;
 
-- Status register record:
type csr_status_register is
record
ei, pei : std_logic;
im, pim : std_logic_vector(7 downto 0);
end record;
 
-- Exception context; this record contains all state that is stored
-- Exception context; this record contains all state that can be manipulated
-- when an exception is taken.
type csr_exception_context is
record
status : csr_status_register;
cause : csr_exception_cause;
badvaddr : std_logic_vector(31 downto 0);
ie, ie1 : std_logic; -- Enable Interrupt bits
cause : csr_exception_cause;
badaddr : std_logic_vector(31 downto 0);
end record;
 
-- Reset value of the status register:
constant CSR_SR_DEFAULT : csr_status_register := (ei => '0', pei => '0', im => x"00", pim => x"00");
--! Creates the value of the mstatus registe from the EI and EI1 bits.
function csr_make_mstatus(ie, ie1 : in std_logic) return std_logic_vector;
 
-- Converts a status register record into an std_logic_vector:
function to_std_logic_vector(input : in csr_status_register)
return std_logic_vector;
 
-- Converts an std_logic_vector into a status register record:
function to_csr_status_register(input : in std_logic_vector(31 downto 0))
return csr_status_register;
 
--! Checks if a control register is writeable.
function csr_is_writeable(csr : in csr_address) return boolean;
 
end package pp_csr;
 
package body pp_csr is
108,37 → 107,21
function to_std_logic_vector(input : in csr_exception_cause)
return std_logic_vector is
begin
return (31 downto 5 => '0') & input;
return (31 => input(5), 30 downto 5 => '0') & input(4 downto 0);
end function to_std_logic_vector;
 
function to_std_logic_vector(input : in csr_status_register)
return std_logic_vector is
function csr_make_mstatus(ie, ie1 : in std_logic) return std_logic_vector is
variable retval : std_logic_vector(31 downto 0);
begin
return input.pim & input.im & (15 downto 4 => '0') & input.pei & input.ei & '1' & '1';
end function to_std_logic_vector;
 
function to_csr_status_register(input : in std_logic_vector(31 downto 0))
return csr_status_register
is
variable retval : csr_status_register;
begin
retval.ei := input(CSR_SR_EI);
retval.pei := input(CSR_SR_PEI);
retval.im := input(23 downto 16);
retval.pim := input(31 downto 24);
retval := (
11 downto 10 => '1', -- PRV3
8 downto 7 => '1', -- PRV2
5 downto 4 => '1', -- PRV1
CSR_SR_IE1 => ie1, -- IE1
2 downto 1 => '1', -- PRV
CSR_SR_IE => ie, -- IE
others => '0');
return retval;
end function to_csr_status_register;
end function csr_make_mstatus;
 
function csr_is_writeable(csr : in csr_address) return boolean is
begin
case csr is
when CSR_FROMHOST | CSR_CYCLE | CSR_CYCLEH | CSR_HARTID
| CSR_TIME | CSR_TIMEH | CSR_INSTRET | CSR_INSTRETH
| CSR_CAUSE | CSR_BADVADDR =>
return false;
when others =>
return true;
end case;
end function csr_is_writeable;
 
end package body pp_csr;
/new-privileged-isa/src/pp_core.vhd
19,7 → 19,7
entity pp_core is
generic(
PROCESSOR_ID : std_logic_vector(31 downto 0) := x"00000000"; --! Processor ID.
RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000000" --! Address of the first instruction to execute.
RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000200" --! Address of the first instruction to execute.
);
port(
-- Control inputs:
67,7 → 67,7
-- by the instret counter:
signal if_count_instruction, id_count_instruction : std_logic;
signal ex_count_instruction, mem_count_instruction : std_logic;
signal wb_count_instruction : std_logic;
signal wb_count_instruction : std_logic;
 
-- CSR read port signals:
signal csr_read_data : std_logic_vector(31 downto 0);
75,9 → 75,13
signal csr_read_address, csr_read_address_p : csr_address;
 
-- Status register outputs:
signal status : csr_status_register;
signal evec : std_logic_vector(31 downto 0);
signal mtvec : std_logic_vector(31 downto 0);
signal mie : std_logic_vector(31 downto 0);
signal ie, ie1 : std_logic;
 
-- Internal interrupt signals:
signal software_interrupt, timer_interrupt : std_logic;
 
-- Load hazard detected in the execute stage:
signal load_hazard_detected : std_logic;
 
182,6 → 186,7
clk => clk,
reset => reset,
timer_clk => timer_clk,
irq => irq,
count_instruction => wb_count_instruction,
fromhost_data => fromhost_data,
fromhost_updated => fromhost_write_en,
195,12 → 200,15
write_mode => wb_csr_write,
exception_context => wb_exception_context,
exception_context_write => wb_exception,
status_out => status,
evec_out => evec
mie_out => mie,
mtvec_out => mtvec,
ie_out => ie,
ie1_out => ie1,
software_interrupt_out => software_interrupt,
timer_interrupt_out => timer_interrupt
);
 
csr_read_address <= id_csr_address when stall_ex = '0' else csr_read_address_p;
 
store_previous_csr_addr: process(clk, stall_ex)
begin
if rising_edge(clk) and stall_ex = '0' then
299,6 → 307,8
stall => stall_ex,
flush => flush_ex,
irq => irq,
software_interrupt => software_interrupt,
timer_interrupt => timer_interrupt,
dmem_address => ex_dmem_address,
dmem_data_size => ex_dmem_data_size,
dmem_data_out => ex_dmem_data_out,
337,9 → 347,11
mem_size_out => ex_mem_size,
count_instruction_in => id_count_instruction,
count_instruction_out => ex_count_instruction,
status_in => status,
evec_in => evec,
evec_out => exception_target,
ie_in => ie,
ie1_in => ie1,
mie_in => mie,
mtvec_in => mtvec,
mtvec_out => exception_target,
decode_exception_in => id_exception,
decode_exception_cause_in => id_exception_cause,
exception_out => exception_taken,
/new-privileged-isa/src/pp_fetch.vhd
11,7 → 11,7
--! @brief Instruction fetch unit.
entity pp_fetch is
generic(
RESET_ADDRESS : std_logic_vector(31 downto 0) := x"00000000"
RESET_ADDRESS : std_logic_vector(31 downto 0)
);
port(
clk : in std_logic;
/new-privileged-isa/testbenches/tb_processor.vhd
27,6 → 27,10
signal clk : std_logic := '0';
constant clk_period : time := 10 ns;
 
-- Timer clock signal:
signal timer_clk : std_logic := '0';
constant timer_clk_period : time := 100 ns;
 
-- Common inputs:
signal reset : std_logic := '1';
 
77,7 → 81,7
) port map(
clk => clk,
reset => reset,
timer_clk => clk,
timer_clk => timer_clk,
imem_address => imem_address,
imem_data_in => imem_data_in,
imem_req => imem_req,
109,6 → 113,18
end if;
end process clock;
 
timer_clock: process
begin
timer_clk <= '0';
wait for timer_clk_period / 2;
timer_clk <= '1';
wait for timer_clk_period / 2;
 
if simulation_finished then
wait;
end if;
end process timer_clock;
 
--! Initializes the instruction memory from file.
imem_init: process
file imem_file : text open READ_MODE is IMEM_FILENAME;
/new-privileged-isa/testbenches/tb_soc.vhd
29,6 → 29,9
signal clk : std_logic;
constant clk_period : time := 10 ns;
 
signal timer_clk : std_logic;
constant timer_clk_period : time := 100 ns;
 
-- Reset:
signal reset : std_logic := '1';
 
204,17 → 207,18
variable input_value : std_logic_vector(31 downto 0);
variable temp : std_logic_vector(31 downto 0);
constant DMEM_START : natural := IMEM_SIZE;
constant DMEM_START_ADDR : natural := IMEM_SIZE;
begin
if not initialized then
-- Read the instruction memory file:
for i in to_integer(unsigned(IMEM_START_ADDR)) to IMEM_SIZE loop
for i in 0 to (IMEM_SIZE / 4) - 1 loop
exit when endfile(imem_file);
 
readline(imem_file, input_line);
hread(input_line, input_value);
 
init_adr_out <= std_logic_vector(to_unsigned(i * 4, init_adr_out'length));
init_adr_out <= std_logic_vector(to_unsigned(to_integer(unsigned(IMEM_START_ADDR)) + (i * 4),
init_adr_out'length));
init_dat_out <= input_value;
init_cyc_out <= '1';
init_stb_out <= '1';
230,13 → 234,12
wait for clk_period;
 
-- Read the data memory file:
for i in 0 to DMEM_SIZE loop
for i in 0 to (DMEM_SIZE / 4) - 1 loop
exit when endfile(dmem_file);
readline(dmem_file, input_line);
hread(input_line, input_value);
 
 
-- Swap endianness, TODO: prevent this, fix scripts/extract_hex.sh
temp(7 downto 0) := input_value(31 downto 24);
temp(15 downto 8) := input_value(23 downto 16);
245,7 → 248,7
 
input_value := temp;
 
init_adr_out <= std_logic_vector(to_unsigned(DMEM_START + (i * 4), init_adr_out'length));
init_adr_out <= std_logic_vector(to_unsigned(DMEM_START_ADDR + (i * 4), init_adr_out'length));
init_dat_out <= input_value;
init_cyc_out <= '1';
init_stb_out <= '1';
277,6 → 280,18
end if;
end process clock;
 
timer_clock: process
begin
timer_clk <= '1';
wait for timer_clk_period / 2;
timer_clk <= '0';
wait for timer_clk_period / 2;
 
if simulation_finished then
wait;
end if;
end process timer_clock;
 
stimulus: process
begin
wait for clk_period * 2;

powered by: WebSVN 2.1.0

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