URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [core/] [proc.vhd] - Rev 5
Compare with Previous | Blame | View Log
----------------------------------------------------------------------------- --! @file --! @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. --! @author Sergey Khabarov - sergeykhbr@gmail.com --! @brief CPU pipeline implementation. ------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; library commonlib; use commonlib.types_common.all; --! RIVER CPU specific library. library riverlib; --! RIVER CPU configuration constants. use riverlib.river_cfg.all; entity Processor is port ( i_clk : in std_logic; -- CPU clock i_nrst : in std_logic; -- Reset. Active LOW. -- Control path: i_req_ctrl_ready : in std_logic; -- ICache is ready to accept request o_req_ctrl_valid : out std_logic; -- Request to ICache is valid o_req_ctrl_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Requesting address to ICache i_resp_ctrl_valid : in std_logic; -- ICache response is valid i_resp_ctrl_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Response address must be equal to the latest request address i_resp_ctrl_data : in std_logic_vector(31 downto 0); -- Read value o_resp_ctrl_ready : out std_logic; -- Data path: i_req_data_ready : in std_logic; -- DCache is ready to accept request o_req_data_valid : out std_logic; -- Request to DCache is valid o_req_data_write : out std_logic; -- Read/Write transaction o_req_data_size : out std_logic_vector(1 downto 0); -- Size [Bytes]: 0=1B; 1=2B; 2=4B; 3=8B o_req_data_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Requesting address to DCache o_req_data_data : out std_logic_vector(RISCV_ARCH-1 downto 0); -- Writing value i_resp_data_valid : in std_logic; -- DCache response is valid i_resp_data_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- DCache response address must be equal to the latest request address i_resp_data_data : in std_logic_vector(RISCV_ARCH-1 downto 0); -- Read value o_resp_data_ready : out std_logic; -- External interrupt pin i_ext_irq : in std_logic; -- PLIC interrupt accordingly with spec o_time : out std_logic_vector(63 downto 0); -- Timer in clock except halt state -- Debug interface: i_dport_valid : in std_logic; -- Debug access from DSU is valid i_dport_write : in std_logic; -- Write command flag i_dport_region : in std_logic_vector(1 downto 0); -- Registers region ID: 0=CSR; 1=IREGS; 2=Control i_dport_addr : in std_logic_vector(11 downto 0); -- Register idx i_dport_wdata : in std_logic_vector(RISCV_ARCH-1 downto 0); -- Write value o_dport_ready : out std_logic; -- Response is ready o_dport_rdata : out std_logic_vector(RISCV_ARCH-1 downto 0); -- Response value -- Debug signals: i_istate : in std_logic_vector(1 downto 0); -- ICache state machine value i_dstate : in std_logic_vector(1 downto 0); -- DCache state machine value i_cstate : in std_logic_vector(1 downto 0) -- CacheTop state machine value ); end; architecture arch_Processor of Processor is type FetchType is record req_fire : std_logic; valid : std_logic; pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); instr : std_logic_vector(31 downto 0); imem_req_valid : std_logic; imem_req_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); predict_miss : std_logic; pipeline_hold : std_logic; instr_buf : std_logic_vector(DBG_FETCH_TRACE_SIZE*64-1 downto 0); end record; type InstructionDecodeType is record pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); instr : std_logic_vector(31 downto 0); instr_valid : std_logic; memop_store : std_logic; memop_load : std_logic; memop_sign_ext : std_logic; memop_size : std_logic_vector(1 downto 0); rv32 : std_logic; -- 32-bits instruction compressed : std_logic; -- C-extension unsigned_op : std_logic; -- Unsigned operands isa_type : std_logic_vector(ISA_Total-1 downto 0); instr_vec : std_logic_vector(Instr_Total-1 downto 0); exception : std_logic; end record; type ExecuteType is record valid : std_logic; instr : std_logic_vector(31 downto 0); pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); npc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); radr1 : std_logic_vector(4 downto 0); radr2 : std_logic_vector(4 downto 0); res_addr : std_logic_vector(4 downto 0); res_data : std_logic_vector(RISCV_ARCH-1 downto 0); trap_ena : std_logic; -- Trap pulse trap_code : std_logic_vector(4 downto 0); -- bit[4] : 1=interrupt; 0=exception; bits[3:0]=code trap_pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- trap on pc xret : std_logic; csr_addr : std_logic_vector(11 downto 0); csr_wena : std_logic; csr_wdata : std_logic_vector(RISCV_ARCH-1 downto 0); memop_sign_ext : std_logic; memop_load : std_logic; memop_store : std_logic; memop_size : std_logic_vector(1 downto 0); memop_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); pipeline_hold : std_logic; -- Hold pipeline from Execution stage breakpoint : std_logic; call : std_logic; ret : std_logic; end record; type MemoryType is record valid : std_logic; instr : std_logic_vector(31 downto 0); pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); pipeline_hold : std_logic; end record; type WriteBackType is record pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); wena : std_logic; waddr : std_logic_vector(4 downto 0); wdata : std_logic_vector(RISCV_ARCH-1 downto 0); end record; type IntRegsType is record rdata1 : std_logic_vector(RISCV_ARCH-1 downto 0); rdata2 : std_logic_vector(RISCV_ARCH-1 downto 0); dport_rdata : std_logic_vector(RISCV_ARCH-1 downto 0); ra : std_logic_vector(RISCV_ARCH-1 downto 0); -- Return address end record; type CsrType is record rdata : std_logic_vector(RISCV_ARCH-1 downto 0); dport_rdata : std_logic_vector(RISCV_ARCH-1 downto 0); ie : std_logic; -- Interrupt enable bit mtvec : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Interrupt descriptor table mode : std_logic_vector(1 downto 0); -- Current processor mode end record; --! 5-stages CPU pipeline type PipelineType is record f : FetchType; -- Fetch instruction stage d : InstructionDecodeType; -- Decode instruction stage e : ExecuteType; -- Execute instruction m : MemoryType; -- Memory load/store w : WriteBackType; -- Write back registers value end record; type DebugType is record core_addr : std_logic_vector(11 downto 0); -- Address of the sub-region register core_wdata : std_logic_vector(RISCV_ARCH-1 downto 0);-- Write data csr_ena : std_logic; -- Region 0: Access to CSR bank is enabled. csr_write : std_logic; -- Region 0: CSR write enable ireg_ena : std_logic; -- Region 1: Access to integer register bank is enabled ireg_write : std_logic; -- Region 1: Integer registers bank write pulse npc_write : std_logic; -- Region 1: npc write enable halt : std_logic; -- Halt signal is equal to hold pipeline clock_cnt : std_logic_vector(63 downto 0); -- Number of clocks excluding halt state executed_cnt : std_logic_vector(63 downto 0); -- Number of executed instruction break_mode : std_logic; -- Behaviour on EBREAK instruction: 0 = halt; 1 = generate trap br_fetch_valid : std_logic; -- Fetch injection address/instr are valid br_address_fetch : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); -- Fetch injection address to skip ebreak instruciton only once br_instr_fetch : std_logic_vector(31 downto 0); -- Real instruction value that was replaced by ebreak end record; signal ireg : IntRegsType; signal csr : CsrType; signal w : PipelineType; signal dbg : DebugType; signal wb_npc_predict : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal wb_ireg_dport_addr : std_logic_vector(4 downto 0); signal wb_exec_dport_npc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); signal w_fetch_pipeline_hold : std_logic; signal w_any_pipeline_hold : std_logic; signal w_exec_pipeline_hold : std_logic; begin w_fetch_pipeline_hold <= w.e.pipeline_hold or w.m.pipeline_hold or dbg.halt; w_any_pipeline_hold <= w.f.pipeline_hold or w.e.pipeline_hold or w.m.pipeline_hold or dbg.halt; w_exec_pipeline_hold <= w.f.pipeline_hold or w.m.pipeline_hold or dbg.halt; wb_ireg_dport_addr <= dbg.core_addr(4 downto 0); wb_exec_dport_npc <= dbg.core_wdata(BUS_ADDR_WIDTH-1 downto 0); fetch0 : InstrFetch port map ( i_clk => i_clk, i_nrst => i_nrst, i_pipeline_hold => w_fetch_pipeline_hold, i_mem_req_ready => i_req_ctrl_ready, o_mem_addr_valid => w.f.imem_req_valid, o_mem_addr => w.f.imem_req_addr, i_mem_data_valid => i_resp_ctrl_valid, i_mem_data_addr => i_resp_ctrl_addr, i_mem_data => i_resp_ctrl_data, o_mem_resp_ready => o_resp_ctrl_ready, i_e_npc => w.e.npc, i_predict_npc => wb_npc_predict, o_predict_miss => w.f.predict_miss, o_mem_req_fire => w.f.req_fire, o_valid => w.f.valid, o_pc => w.f.pc, o_instr => w.f.instr, o_hold => w.f.pipeline_hold, i_br_fetch_valid => dbg.br_fetch_valid, i_br_address_fetch => dbg.br_address_fetch, i_br_instr_fetch => dbg.br_instr_fetch, o_instr_buf => w.f.instr_buf); dec0 : InstrDecoder port map ( i_clk => i_clk, i_nrst => i_nrst, i_any_hold => w_any_pipeline_hold, i_f_valid => w.f.valid, i_f_pc => w.f.pc, i_f_instr => w.f.instr, o_valid => w.d.instr_valid, o_pc => w.d.pc, o_instr => w.d.instr, o_memop_store => w.d.memop_store, o_memop_load => w.d.memop_load, o_memop_sign_ext => w.d.memop_sign_ext, o_memop_size => w.d.memop_size, o_unsigned_op => w.d.unsigned_op, o_rv32 => w.d.rv32, o_compressed => w.d.compressed, o_isa_type => w.d.isa_type, o_instr_vec => w.d.instr_vec, o_exception => w.d.exception); exec0 : InstrExecute port map ( i_clk => i_clk, i_nrst => i_nrst, i_pipeline_hold => w_exec_pipeline_hold, i_d_valid => w.d.instr_valid, i_d_pc => w.d.pc, i_d_instr => w.d.instr, i_wb_done => w.m.valid, i_memop_store => w.d.memop_store, i_memop_load => w.d.memop_load, i_memop_sign_ext => w.d.memop_sign_ext, i_memop_size => w.d.memop_size, i_unsigned_op => w.d.unsigned_op, i_rv32 => w.d.rv32, i_compressed => w.d.compressed, i_isa_type => w.d.isa_type, i_ivec => w.d.instr_vec, i_ie => csr.ie, i_mtvec => csr.mtvec, i_mode => csr.mode, i_break_mode => dbg.break_mode, i_unsup_exception => w.d.exception, i_ext_irq => i_ext_irq, i_dport_npc_write => dbg.npc_write, i_dport_npc => wb_exec_dport_npc, o_radr1 => w.e.radr1, i_rdata1 => ireg.rdata1, o_radr2 => w.e.radr2, i_rdata2 => ireg.rdata2, o_res_addr => w.e.res_addr, o_res_data => w.e.res_data, o_pipeline_hold => w.e.pipeline_hold, o_xret => w.e.xret, o_csr_addr => w.e.csr_addr, o_csr_wena => w.e.csr_wena, i_csr_rdata => csr.rdata, o_csr_wdata => w.e.csr_wdata, o_trap_ena => w.e.trap_ena, o_trap_code => w.e.trap_code, o_trap_pc => w.e.trap_pc, o_memop_sign_ext => w.e.memop_sign_ext, o_memop_load => w.e.memop_load, o_memop_store => w.e.memop_store, o_memop_size => w.e.memop_size, o_memop_addr => w.e.memop_addr, o_valid => w.e.valid, o_pc => w.e.pc, o_npc => w.e.npc, o_instr => w.e.instr, o_breakpoint => w.e.breakpoint, o_call => w.e.call, o_ret => w.e.ret); mem0 : MemAccess port map ( i_clk => i_clk, i_nrst => i_nrst, i_e_valid => w.e.valid, i_e_pc => w.e.pc, i_e_instr => w.e.instr, i_res_addr => w.e.res_addr, i_res_data => w.e.res_data, i_memop_sign_ext => w.e.memop_sign_ext, i_memop_load => w.e.memop_load, i_memop_store => w.e.memop_store, i_memop_size => w.e.memop_size, i_memop_addr => w.e.memop_addr, o_waddr => w.w.waddr, o_wena => w.w.wena, o_wdata => w.w.wdata, i_mem_req_ready => i_req_data_ready, o_mem_valid => o_req_data_valid, o_mem_write => o_req_data_write, o_mem_sz => o_req_data_size, o_mem_addr => o_req_data_addr, o_mem_data => o_req_data_data, i_mem_data_valid => i_resp_data_valid, i_mem_data_addr => i_resp_data_addr, i_mem_data => i_resp_data_data, o_mem_resp_ready => o_resp_data_ready, o_hold => w.m.pipeline_hold, o_valid => w.m.valid, o_pc => w.m.pc, o_instr => w.m.instr); predic0 : BranchPredictor port map ( i_clk => i_clk, i_nrst => i_nrst, i_req_mem_fire => w.f.req_fire, i_resp_mem_valid => i_resp_ctrl_valid, i_resp_mem_addr => i_resp_ctrl_addr, i_resp_mem_data => i_resp_ctrl_data, i_f_predic_miss => w.f.predict_miss, i_e_npc => w.e.npc, i_ra => ireg.ra, o_npc_predict => wb_npc_predict); iregs0 : RegIntBank port map ( i_clk => i_clk, i_nrst => i_nrst, i_radr1 => w.e.radr1, o_rdata1 => ireg.rdata1, i_radr2 => w.e.radr2, o_rdata2 => ireg.rdata2, i_waddr => w.w.waddr, i_wena => w.w.wena, i_wdata => w.w.wdata, i_dport_addr => wb_ireg_dport_addr, i_dport_ena => dbg.ireg_ena, i_dport_write => dbg.ireg_write, i_dport_wdata => dbg.core_wdata, o_dport_rdata => ireg.dport_rdata, o_ra => ireg.ra); -- Return address csr0 : CsrRegs port map ( i_clk => i_clk, i_nrst => i_nrst, i_xret => w.e.xret, i_addr => w.e.csr_addr, i_wena => w.e.csr_wena, i_wdata => w.e.csr_wdata, o_rdata => csr.rdata, i_break_mode => dbg.break_mode, i_breakpoint => w.e.breakpoint, i_trap_ena => w.e.trap_ena, i_trap_code => w.e.trap_code, i_trap_pc => w.e.trap_pc, o_ie => csr.ie, o_mode => csr.mode, o_mtvec => csr.mtvec, i_dport_ena => dbg.csr_ena, i_dport_write => dbg.csr_write, i_dport_addr => dbg.core_addr, i_dport_wdata => dbg.core_wdata, o_dport_rdata => csr.dport_rdata); dbg0 : DbgPort port map ( i_clk => i_clk, i_nrst => i_nrst, i_dport_valid => i_dport_valid, i_dport_write => i_dport_write, i_dport_region => i_dport_region, i_dport_addr => i_dport_addr, i_dport_wdata => i_dport_wdata, o_dport_ready => o_dport_ready, o_dport_rdata => o_dport_rdata, o_core_addr => dbg.core_addr, o_core_wdata => dbg.core_wdata, o_csr_ena => dbg.csr_ena, o_csr_write => dbg.csr_write, i_csr_rdata => csr.dport_rdata, o_ireg_ena => dbg.ireg_ena, o_ireg_write => dbg.ireg_write, o_npc_write => dbg.npc_write, i_ireg_rdata => ireg.dport_rdata, i_pc => w.e.pc, i_npc => w.e.npc, i_e_valid => w.e.valid, i_e_call => w.e.call, i_e_ret => w.e.ret, i_m_valid => w.m.valid, o_clock_cnt => dbg.clock_cnt, o_executed_cnt => dbg.executed_cnt, o_halt => dbg.halt, i_ebreak => w.e.breakpoint, o_break_mode => dbg.break_mode, o_br_fetch_valid => dbg.br_fetch_valid, o_br_address_fetch => dbg.br_address_fetch, o_br_instr_fetch => dbg.br_instr_fetch, i_istate => i_istate, i_dstate => i_dstate, i_cstate => i_cstate, i_instr_buf => w.f.instr_buf); o_req_ctrl_valid <= w.f.imem_req_valid; o_req_ctrl_addr <= w.f.imem_req_addr; o_time <= dbg.clock_cnt; end;