Line 186... |
Line 186... |
constant sreg_resume_ack_c : natural := 2; -- -/w: CPU starts resuming
|
constant sreg_resume_ack_c : natural := 2; -- -/w: CPU starts resuming
|
constant sreg_execute_req_c : natural := 3; -- r/-: DM requests to execute program buffer
|
constant sreg_execute_req_c : natural := 3; -- r/-: DM requests to execute program buffer
|
constant sreg_execute_ack_c : natural := 4; -- -/w: CPU starts to execute program buffer
|
constant sreg_execute_ack_c : natural := 4; -- -/w: CPU starts to execute program buffer
|
constant sreg_exception_ack_c : natural := 5; -- -/w: CPU has detected an exception
|
constant sreg_exception_ack_c : natural := 5; -- -/w: CPU has detected an exception
|
|
|
-- code ROM for "park loop" --
|
-- code ROM containing "park loop" --
|
type code_rom_file_t is array (0 to 31) of std_ulogic_vector(31 downto 0);
|
type code_rom_file_t is array (0 to 31) of std_ulogic_vector(31 downto 0);
|
constant code_rom_file : code_rom_file_t := (
|
constant code_rom_file : code_rom_file_t := (
|
00000000 => x"0180006f",
|
00000000 => x"0180006f",
|
00000001 => x"7b241073",
|
00000001 => x"7b241073",
|
00000002 => x"02000413",
|
00000002 => x"02000413",
|
Line 238... |
Line 238... |
dm_controller: process(clk_i)
|
dm_controller: process(clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if (dm_reg.dmcontrol_dmactive = '0') or (dmi_rstn_i = '0') then -- DM reset / DM disabled
|
if (dm_reg.dmcontrol_dmactive = '0') or (dmi_rstn_i = '0') then -- DM reset / DM disabled
|
dm_ctrl.state <= CMD_IDLE;
|
dm_ctrl.state <= CMD_IDLE;
|
dm_ctrl.ldsw_progbuf <= instr_nop_c;
|
dm_ctrl.ldsw_progbuf <= (others => '-');
|
dci.execute_req <= '0';
|
dci.execute_req <= '0';
|
dm_ctrl.pbuf_en <= '0';
|
dm_ctrl.pbuf_en <= '-';
|
--
|
--
|
dm_ctrl.illegal_cmd <= '-';
|
dm_ctrl.illegal_cmd <= '-';
|
dm_ctrl.illegal_state <= '-';
|
dm_ctrl.illegal_state <= '-';
|
dm_ctrl.cmderr <= "000";
|
dm_ctrl.cmderr <= "000";
|
--
|
--
|
Line 304... |
Line 304... |
dm_ctrl.ldsw_progbuf <= instr_lw_c;
|
dm_ctrl.ldsw_progbuf <= instr_lw_c;
|
dm_ctrl.ldsw_progbuf(31 downto 20) <= dataaddr_c; -- source address
|
dm_ctrl.ldsw_progbuf(31 downto 20) <= dataaddr_c; -- source address
|
dm_ctrl.ldsw_progbuf(11 downto 07) <= dm_reg.command(4 downto 0); -- "regno" = destination register
|
dm_ctrl.ldsw_progbuf(11 downto 07) <= dm_reg.command(4 downto 0); -- "regno" = destination register
|
end if;
|
end if;
|
else
|
else
|
dm_ctrl.ldsw_progbuf <= instr_nop_c;
|
dm_ctrl.ldsw_progbuf <= instr_nop_c; -- NOP - do nothing
|
end if;
|
end if;
|
--
|
--
|
if (dm_reg.command(18) = '1') then -- "postexec" - execute DMI program buffer
|
if (dm_reg.command(18) = '1') then -- "postexec" - execute program buffer
|
dm_ctrl.pbuf_en <= '1';
|
dm_ctrl.pbuf_en <= '1';
|
else -- empty program buffer, execute NOPs
|
else -- execute all program buffer entries as NOPs
|
dm_ctrl.pbuf_en <= '0';
|
dm_ctrl.pbuf_en <= '0';
|
end if;
|
end if;
|
--
|
--
|
dm_ctrl.state <= CMD_EXE_TRIGGER;
|
dm_ctrl.state <= CMD_EXE_TRIGGER;
|
|
|
Line 324... |
Line 324... |
dm_ctrl.state <= CMD_EXE_BUSY;
|
dm_ctrl.state <= CMD_EXE_BUSY;
|
end if;
|
end if;
|
|
|
when CMD_EXE_BUSY => -- wait for CPU to finish
|
when CMD_EXE_BUSY => -- wait for CPU to finish
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (dci.halt_ack = '1') then -- CPU is parked again -> execution done
|
if (dci.halt_ack = '1') then -- CPU is parked (halted) again -> execution done
|
dm_ctrl.state <= CMD_IDLE;
|
dm_ctrl.state <= CMD_IDLE;
|
end if;
|
end if;
|
|
|
when CMD_EXE_ERROR => -- delay cycle for error to arrive abstracts.cmderr
|
when CMD_EXE_ERROR => -- delay cycle for error to arrive abstracts.cmderr
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
Line 339... |
Line 339... |
dm_ctrl.state <= CMD_IDLE;
|
dm_ctrl.state <= CMD_IDLE;
|
|
|
end case;
|
end case;
|
|
|
|
|
-- error flag register --
|
-- error flags --
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (dm_ctrl.cmderr = "000") then
|
if (dm_ctrl.cmderr = "000") then -- set new error
|
if (dm_ctrl.illegal_state = '1') then -- cannot execute since hart is not in expected state
|
if (dm_ctrl.illegal_state = '1') then -- cannot execute since hart is not in expected state
|
dm_ctrl.cmderr <= "100";
|
dm_ctrl.cmderr <= "100";
|
elsif (dci.exception_ack = '1') then -- exception during execution
|
elsif (dci.exception_ack = '1') then -- exception during execution
|
dm_ctrl.cmderr <= "011";
|
dm_ctrl.cmderr <= "011";
|
elsif (dm_ctrl.illegal_cmd = '1') then -- unsupported command
|
elsif (dm_ctrl.illegal_cmd = '1') then -- unsupported command
|
Line 542... |
Line 542... |
case dmi_req_addr_i is
|
case dmi_req_addr_i is
|
|
|
-- debug module status register --
|
-- debug module status register --
|
when addr_dmstatus_c =>
|
when addr_dmstatus_c =>
|
dmi_resp_data_o(31 downto 23) <= (others => '0'); -- reserved (r/-)
|
dmi_resp_data_o(31 downto 23) <= (others => '0'); -- reserved (r/-)
|
dmi_resp_data_o(22) <= '1'; -- impebreak (r/-): there is an implicit ebreak instruction after the program visible buffer
|
dmi_resp_data_o(22) <= '1'; -- impebreak (r/-): there is an implicit ebreak instruction after the visible program buffer
|
dmi_resp_data_o(21 downto 20) <= (others => '0'); -- reserved (r/-)
|
dmi_resp_data_o(21 downto 20) <= (others => '0'); -- reserved (r/-)
|
dmi_resp_data_o(19) <= dm_ctrl.hart_reset; -- allhavereset (r/-): there is only one hart that can be reset
|
dmi_resp_data_o(19) <= dm_ctrl.hart_reset; -- allhavereset (r/-): there is only one hart that can be reset
|
dmi_resp_data_o(18) <= dm_ctrl.hart_reset; -- anyhavereset (r/-): there is only one hart that can be reset
|
dmi_resp_data_o(18) <= dm_ctrl.hart_reset; -- anyhavereset (r/-): there is only one hart that can be reset
|
dmi_resp_data_o(17) <= dm_ctrl.hart_resume_ack; -- allresumeack (r/-): there is only one hart that can acknowledge resume request
|
dmi_resp_data_o(17) <= dm_ctrl.hart_resume_ack; -- allresumeack (r/-): there is only one hart that can acknowledge resume request
|
dmi_resp_data_o(16) <= dm_ctrl.hart_resume_ack; -- anyresumeack (r/-): there is only one hart that can acknowledge resume request
|
dmi_resp_data_o(16) <= dm_ctrl.hart_resume_ack; -- anyresumeack (r/-): there is only one hart that can acknowledge resume request
|
Line 621... |
Line 621... |
when addr_progbuf0_c =>
|
when addr_progbuf0_c =>
|
dmi_resp_data_o <= dm_reg.progbuf(0); -- program buffer 0
|
dmi_resp_data_o <= dm_reg.progbuf(0); -- program buffer 0
|
when addr_progbuf1_c =>
|
when addr_progbuf1_c =>
|
dmi_resp_data_o <= dm_reg.progbuf(1); -- program buffer 1
|
dmi_resp_data_o <= dm_reg.progbuf(1); -- program buffer 1
|
|
|
-- system bus access control and status (r/-) --
|
-- -- system bus access control and status (r/-) --
|
when addr_sbcs_c =>
|
-- when addr_sbcs_c =>
|
dmi_resp_data_o <= (others => '0'); -- bus access not implemented
|
-- dmi_resp_data_o <= (others => '0'); -- bus access not implemented
|
|
|
-- halt summary 0 (r/-) --
|
-- halt summary 0 (r/-) --
|
when addr_haltsum0_c =>
|
when addr_haltsum0_c =>
|
dmi_resp_data_o(0) <= dm_ctrl.hart_halted; -- hart is halted
|
dmi_resp_data_o(0) <= dm_ctrl.hart_halted; -- hart is halted
|
|
|
Line 667... |
Line 667... |
-- **************************************************************************************************************************
|
-- **************************************************************************************************************************
|
|
|
-- Access Control ------------------------------------------------------------------------
|
-- Access Control ------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
acc_en <= '1' when (cpu_addr_i(hi_abb_c downto lo_abb_c) = dm_base_c(hi_abb_c downto lo_abb_c)) else '0';
|
acc_en <= '1' when (cpu_addr_i(hi_abb_c downto lo_abb_c) = dm_base_c(hi_abb_c downto lo_abb_c)) else '0';
|
maddr <= cpu_addr_i(lo_abb_c-1 downto lo_abb_c-2);
|
maddr <= cpu_addr_i(lo_abb_c-1 downto lo_abb_c-2); -- (sub-)module select address
|
rden <= acc_en and cpu_rden_i;
|
rden <= acc_en and cpu_rden_i;
|
wren <= acc_en and cpu_wren_i;
|
wren <= acc_en and cpu_wren_i;
|
|
|
|
|
-- Write Access ---------------------------------------------------------------------------
|
-- Write Access ---------------------------------------------------------------------------
|
Line 709... |
Line 709... |
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
cpu_ack_o <= rden or wren;
|
cpu_ack_o <= rden or wren;
|
cpu_data_o <= (others => '0');
|
cpu_data_o <= (others => '0');
|
if (rden = '1') then -- output gate
|
if (rden = '1') then -- output gate
|
case maddr is -- read data select
|
case maddr is -- module select
|
when "00" => -- code ROM
|
when "00" => -- code ROM
|
cpu_data_o <= code_rom_file(to_integer(unsigned(cpu_addr_i(6 downto 2))));
|
cpu_data_o <= code_rom_file(to_integer(unsigned(cpu_addr_i(6 downto 2))));
|
when "01" => -- program buffer
|
when "01" => -- program buffer
|
cpu_data_o <= cpu_progbuf(to_integer(unsigned(cpu_addr_i(3 downto 2))));
|
cpu_data_o <= cpu_progbuf(to_integer(unsigned(cpu_addr_i(3 downto 2))));
|
when "10" => -- data buffer
|
when "10" => -- data buffer
|